Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1U90Dk-0002fU-11 for pgsql-performance@arkaria.postgresql.org; Fri, 22 Feb 2013 21:31:56 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.72) (envelope-from ) id 1U90Dj-0006nm-Go for pgsql-performance@arkaria.postgresql.org; Fri, 22 Feb 2013 21:31:55 +0000 Received: from makus.postgresql.org ([2001:4800:7903:4::125]) by malur.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1U90Dh-0006ng-Vb for pgsql-performance@postgresql.org; Fri, 22 Feb 2013 21:31:54 +0000 Received: from mail-lb0-f179.google.com ([209.85.217.179]) by makus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1U90Dg-0008JL-4J for pgsql-performance@postgresql.org; Fri, 22 Feb 2013 21:31:53 +0000 Received: by mail-lb0-f179.google.com with SMTP id j14so896975lbo.38 for ; Fri, 22 Feb 2013 13:31:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:sender:date:from:to:cc:message-id:in-reply-to:references :subject:x-mailer:mime-version:content-type :content-transfer-encoding:content-disposition; bh=P5YnSDpdVlG/nhTpgpuC47QpMqaiSXYOgOGYZ2cJNBQ=; b=bHJc+jaDJv1KjYNd1o0xDO3TignCpfjl5ST/iUefVAIwOHaa7Clcu+RiESPxGSEDDp EBbkLx9xgWckkw8Rjgt7FEw2se6EsrjRlahu9hqUW1DNlDBr1KDjQJdBVKBGj3C7RzTP WaZd+bt8/0nurJfuCR76BD4VPvB7lJp5KxwKp0p29ub21cXcPjxt5Syfno+EJnau9xaZ /xejhzDqrcI77mnrLIJJeCdVMrsZe3SooqYHiDDLZafyLOp/MWv8OmP/sG7YSC3gy1Fy pRWnO4P1cO4JRbXeNjD4nLfVGJRbp6nBJE0guHjiSMYSuem2BMD9VlE+8UUNfDbpbEZb gfQg== X-Received: by 10.152.132.36 with SMTP id or4mr3059855lab.8.1361568710535; Fri, 22 Feb 2013 13:31:50 -0800 (PST) Received: from [10.0.1.14] ([217.14.6.25]) by mx.google.com with ESMTPS id z1sm1318883lbk.2.2013.02.22.13.31.49 (version=TLSv1 cipher=RC4-SHA bits=128/128); Fri, 22 Feb 2013 13:31:49 -0800 (PST) Date: Fri, 22 Feb 2013 22:31:48 +0100 From: Alexander Staubo To: Tom Lane Cc: pgsql-performance@postgresql.org Message-ID: In-Reply-To: <7707.1361565216@sss.pgh.pa.us> References: <19B2B4ECC4724A438200C54257BA8B20@gmail.com> <7707.1361565216@sss.pgh.pa.us> Subject: Re: Bad query plan with high-cardinality column X-Mailer: sparrow 1.6.4 (build 1178) MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Content-Disposition: inline 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 On Friday, February 22, 2013 at 21:33 , Tom Lane wrote: > The reason is that the LIMIT may stop the query before it's scanned all > of the index. The planner estimates on the assumption that the desired > rows are roughly uniformly distributed within the created_at index, and > on that assumption, it looks like this query will stop fairly soon ... > but evidently, that's wrong. On the other hand, it knows quite well > that the other plan will require pulling out 5000-some rows and then > sorting them before it can return anything, so that's not going to be > exactly instantaneous either. > > In this example, I'll bet that conversation_id and created_at are pretty > strongly correlated, and that most or all of the rows with that specific > conversation_id are quite far down the created_at ordering, so that the > search through the index takes a long time to run. OTOH, with another > conversation_id the same plan might run almost instantaneously. That's right. So I created a composite index, and not only does this make the plan correct, but the planner now chooses a much more efficient plan than the previous index that indexed only on "conversation_id": Limit (cost=0.00..30.80 rows=13 width=12) (actual time=0.042..0.058 rows=13 loops=1) Buffers: shared hit=8 -> Index Scan using index_comments_on_conversation_id_and_created_at on comments (cost=0.00..14127.83 rows=5964 width=12) (actual time=0.039..0.054 rows=13 loops=1) Index Cond: (conversation_id = 3975979) Buffers: shared hit=8 Total runtime: 0.094 ms Is this because it can get the value of "created_at" from the index, or is it because it can know that the index is pre-sorted, or both? Very impressed that Postgres can use a multi-column index for this. I just assumed, wrongly, that it couldn't. I will have to go review my other tables now and see if they can benefit from multi-column indexes. Thanks! -- Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-performance