Received: from localhost (unknown [200.46.204.183]) by postgresql.org (Postfix) with ESMTP id A909E64FCDF for ; Mon, 1 Sep 2008 09:52:59 -0300 (ADT) Received: from postgresql.org ([200.46.204.86]) by localhost (mx1.hub.org [200.46.204.183]) (amavisd-maia, port 10024) with ESMTP id 04422-02 for ; Mon, 1 Sep 2008 09:52:51 -0300 (ADT) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from fk-out-0910.google.com (fk-out-0910.google.com [209.85.128.184]) by postgresql.org (Postfix) with ESMTP id 6D8DA64FCD2 for ; Mon, 1 Sep 2008 09:52:55 -0300 (ADT) Received: by fk-out-0910.google.com with SMTP id e30so1437932fke.3 for ; Mon, 01 Sep 2008 05:52:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from:to :subject:cc:in-reply-to:mime-version:content-type :content-transfer-encoding:content-disposition:references; bh=p1iDFZBDDdDemXqHPXtocnSs+Tig7CyIprNtGLIzmE4=; b=H9yRr5/ClZlL4/MWnbKw5jJv6fq+gMAjNY6PBHB5LjTUQeMt8MgfchZ9nG+gDi66EE fTrZQAAggyYahzrIvciWEKrC+m2bLC7fIyHsq2EIV4JUdEEGiWfeD8Ihi6erq8tkbFPQ S4Qw/0ldfrnST5xG8QSUaExB96PeghZu7UD8A= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:to:subject:cc:in-reply-to:mime-version :content-type:content-transfer-encoding:content-disposition :references; b=KatkGhxfk/fGecsjRFJKmHsueS4D/afM8ASgouZpbnS8xhaT4DI8FMkDfaFVF/j026 TihRTR9Nfp9dtxE8ZGztO3q5hyQ37x0fnDtWo82QD0oreTNqkgUR4vZz/WZXyqDXruTZ vhnB/OyT2hSMO5IhAoGt3n6L6UdQ20+mQDTAM= Received: by 10.181.25.18 with SMTP id c18mr4895435bkj.8.1220273573930; Mon, 01 Sep 2008 05:52:53 -0700 (PDT) Received: by 10.180.250.16 with HTTP; Mon, 1 Sep 2008 05:52:53 -0700 (PDT) Message-ID: <162867790809010552o624a347aif0eb5fc71e7bbad@mail.gmail.com> Date: Mon, 1 Sep 2008 14:52:53 +0200 From: "Pavel Stehule" To: "David West" Subject: Re: limit clause breaks query planner? Cc: pgsql-performance@postgresql.org In-Reply-To: <1683189597512580954@unknownmsgid> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-Disposition: inline References: <1683189597512580954@unknownmsgid> X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0 tagged_above=0 required=5 tests=none X-Spam-Level: X-Archive-Number: 200809/6 X-Sequence-Number: 31319 Hello you should partial index create index foo(b) on mytable where a is null; regards Pavel Stehule 2008/9/1 David West : > Hi, > > > > I have a single table with about 10 million rows, and two indexes. Index A > is on a column A with 95% null values. Index B is on a column B with about > 10 values, ie. About a million rows of each value. > > > > When I do a simple query on the table (no joins) with the following > condition: > > A is null AND > > B = '21' > > > > it uses the correct index, index B. However, when I add a limit clause of > 15, postgres decides to do a sequential scan :s. Looking at the results > from explain: > > > > "Limit (cost=0.00..3.69 rows=15 width=128)" > > " -> Seq Scan on my_table this_ (cost=0.00..252424.24 rows=1025157 > width=128)" > > " Filter: ((A IS NULL) AND ((B)::text = '21'::text))" > > > > It appears that postgres is (very incorrectly) assuming that it will only > have to retrieve 15 rows on a sequential scan, and gives a total cost of > 3.69. In reality, it has to scan many rows forward until it finds the > correct value, yielding very poor performance for my table. > > > > If I disable sequential scan (set enable_seqscan=false) it then incorrectly > uses the index A that has 95% null values: it seems to incorrectly apply the > same logic again that it will only have to retrieve 15 rows with the limit > clause, and thinks that the index scan using A is faster than index scan B. > > > > Only by deleting the index on A and disabling sequential scan will it use > the correct index, which is of course by far the fastest. > > > > Is there an assumption in the planner that a limit of 15 will mean that > postgres will only have to read 15 rows? If so is this a bad assumption? > If a particular query is faster without a limit, then surely it will also be > faster with the limit. > > > > Any workarounds for this? > > > > Thanks > > David