Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eHWf5-0000tc-Sj for pgsql-performance@arkaria.postgresql.org; Wed, 22 Nov 2017 15:10:03 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eHWf5-0006Cc-6v for pgsql-performance@arkaria.postgresql.org; Wed, 22 Nov 2017 15:10:03 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1eHWf5-0006CT-1J for pgsql-performance@lists.postgresql.org; Wed, 22 Nov 2017 15:10:03 +0000 Received: from mx1.mailbox.org ([80.241.60.212]) by magus.postgresql.org with esmtps (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1eHWf1-0005gr-V1 for pgsql-performance@lists.postgresql.org; Wed, 22 Nov 2017 15:10:02 +0000 Received: from smtp1.mailbox.org (smtp1.mailbox.org [80.241.60.240]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.mailbox.org (Postfix) with ESMTPS id 7FBDB474A7; Wed, 22 Nov 2017 16:09:57 +0100 (CET) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by hefe.heinlein-support.de (hefe.heinlein-support.de [91.198.250.172]) (amavisd-new, port 10030) with ESMTP id VydpBIQ9L2g3; Wed, 22 Nov 2017 16:09:55 +0100 (CET) Message-ID: <1511363394.2553.68.camel@cybertec.at> Subject: Re: Bad estimates From: Laurenz Albe To: Artur =?UTF-8?Q?Zaj=C4=85c?= , pgsql-performance@lists.postgresql.org Date: Wed, 22 Nov 2017 16:09:54 +0100 In-Reply-To: <03b401d3639e$5d7493a0$185dbae0$@ang.com.pl> References: <03b401d3639e$5d7493a0$185dbae0$@ang.com.pl> Organization: Cybertec Content-Type: text/plain; charset="UTF-8" Mime-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk Artur ZajÄ…c wrote: > We have table created like this: > > CREATE TABLE xyz AS SELECT generate_series(1,10000000,1) AS gs; > > Now: > > explain analyze select * from xyz where gs&1=1; > Seq Scan on xyz (cost=0.00..260815.38 rows=68920 width=4) > (actual time=0.044..2959.728 rows=5000000 loops=1) > Filter: ((gs & 1) = 1) > Rows Removed by Filter: 5000000 [...] > And one more clause: > > explain analyze select * from xyz where gs&1=1 and gs&2=2 and gs&4=4; > Seq Scan on xyz (cost=0.00..398655.62 rows=2 width=4) > (actual time=0.052..3329.422 rows=1250000 loops=1) > Filter: (((gs & 1) = 1) AND ((gs & 2) = 2) AND ((gs & 4) = 4)) > Rows Removed by Filter: 8750000 > As we can see estimates differs significally from the actual records count - > only three clauses are reducing estimated number of records from 10000000 to > 2. > > I noticed that each additional clause reduces the number about 200 times and > define DEFAULT_NUM_DISTINCT is responsible for this behaviur. > > I think that this variable should be lower or maybe estimation using > DEFAULT_NUM_DISTTINCT should be done once per table. The problem is that the expression "gs & 1" is a black box for the optimizer; it cannot estimate how selective the condition is and falls back to a default value that is too low. You can create an index to a) improve the estimate and b) speed up the queries: CREATE INDEX ON xyz ((gs & 1), (gs & 2), (gs & 4)); Don't forget to ANALYZE afterwards. Yours, Laurenz Albe