Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1YFQVQ-0002FZ-N7 for pgsql-performance@arkaria.postgresql.org; Sun, 25 Jan 2015 16:57:48 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.80) (envelope-from ) id 1YFQVQ-0000y2-2R for pgsql-performance@arkaria.postgresql.org; Sun, 25 Jan 2015 16:57:48 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1YFQVN-0000xt-SC for pgsql-performance@postgresql.org; Sun, 25 Jan 2015 16:57:46 +0000 Received: from mail-wg0-f42.google.com ([74.125.82.42]) by makus.postgresql.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1YFQVK-0002ko-6v for pgsql-performance@postgresql.org; Sun, 25 Jan 2015 16:57:43 +0000 Received: by mail-wg0-f42.google.com with SMTP id x13so5409495wgg.1 for ; Sun, 25 Jan 2015 08:57:39 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:message-id:date:from:organization:user-agent :mime-version:to:subject:references:in-reply-to:content-type :content-transfer-encoding; bh=7mcqLqveFXg/rQyxr6G7m3eYvnDI+ZbEpdUNEZn3VC0=; b=IJ0j9jTFk0Cxz9AABx3j+H4fmaTfqdoHIaQ9Fr/tqp7Mx0DPnNHYv+lpZo2H/QwV+5 N5r38qMU7KtTCKwrbI/NL6/I+MysTCceOrq2cC8SXJKs1upveGV3e0z7XE7O81NmVfvQ aXshJbsmFxwIiJzrQivqN2Jri5ktNmL7CCRy4BIDdoZpd74axb/Ra98X7fyeYawHYyLO AeA6bdEqINjW4FqsgSdMy+fVbHbfE//LDfOkEPteUv9IrQK1h9ZKqTWH/MoesAjjdytp bxqxa+aI/a/RErFKsdBzD/KBTrHdPbaaD1pR8G7tlkzE34+jQ6aW4t7171GLIOUy/AIg YOEg== X-Gm-Message-State: ALoCoQn3F1SZMikAP5VhI1SiyYguDVBKHIMy3pVNVWWTlsiouO50BTtk7JSWR+/cks2vNg8NLxL+xKybDSabHQRt15gd8UcQ9b1Wl6/do4+gT01BA/hmnALlSdpJkbKdY1yACei6fFrvTlDz6tlYxMJnqTLunYWSSqAIr9ayIC1bG4jBkgfSwMrNtSBZYebUWgOmEdqrjiPb X-Received: by 10.194.189.138 with SMTP id gi10mr36643546wjc.86.1422205059725; Sun, 25 Jan 2015 08:57:39 -0800 (PST) Received: from [192.168.1.163] (ip-78-45-139-138.net.upcbroadband.cz. [78.45.139.138]) by mx.google.com with ESMTPSA id cf12sm10829982wjb.10.2015.01.25.08.57.38 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 25 Jan 2015 08:57:39 -0800 (PST) Message-ID: <54C52080.90708@2ndquadrant.com> Date: Sun, 25 Jan 2015 17:57:36 +0100 From: Tomas Vondra Organization: 2ndQuadrant User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 MIME-Version: 1.0 To: pgsql-performance@postgresql.org Subject: Re: Query performance References: In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Pg-Spam-Score: -2.6 (--) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-performance Precedence: bulk Sender: pgsql-performance-owner@postgresql.org Hi, On 25.1.2015 07:38, Joe Van Dyk wrote: > > Here's one that's not quite as well: http://explain.depesz.com/s/SgT As Pavel already pointed out, the first problem is this part of the plan: Seq Scan on events e2 (cost=0.00..120,179.60 rows=4,450,241 width=51) (actual time=0.014..33,773.370 rows=4,450,865 loops=1) Filter: (product_id <> '81716'::citext) Consuming ~33 seconds of the runtime. If you can make this faster somehow (e.g. by getting rid of the citext cast), that'd be nice. Another issue is that the hashjoin is batched: Buckets: 65536 Batches: 8 Memory Usage: 46085kB The hash preparation takes ~40 seconds, so maybe try to give it a bit more memory - I assume you have work_mem=64MB, so try doubling that (ISTM 512MB should work with a single batch). Maybe this won't really improve the performance, though. It still has to process ~4.5M rows. Increasing the work mem could also result in switching to hash aggregate, making the sort (~30 seconds) unnecessary. Anyway, ISTM this works as expected, i.e. (a) with rare product_id values the queries are fast (b) with common product_id values the queries are slow That's expected, because (b) needs to process much more data. I don't think you can magically make it run as fast as (a). The best solution might be to keep a pre-aggregated results - I don't think you really need exact answers when recommending "similar" products. I also wonder if you really need to join the tables? I mean, what if you do something like this: CREATE TABLE events_aggregated AS SELECT site_id, array_agg(product_id) AS product_ids, count(nullif(e2.type='viewed', false)) view_count, count(nullif(e2.type='purchased', false)) purchase_count FROM events GROUP BY 1; and then using intarray with GIN indexes to query this table? Something like this: CREATE products_agg_idx ON aggregated USING GIN (product_ids gin__int_ops); SELECT * FROM events_aggregated WHERE product_ids @> ARRAY['82503']; regards -- Tomas Vondra http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-performance