Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cUDUz-0005O2-DD for pgsql-performance@arkaria.postgresql.org; Thu, 19 Jan 2017 14:15:33 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1cUDUz-000584-0C for pgsql-performance@arkaria.postgresql.org; Thu, 19 Jan 2017 14:15:33 +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 1cUDTJ-0002ln-3N for pgsql-performance@postgresql.org; Thu, 19 Jan 2017 14:13:49 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1cUDTF-0004zk-Mw for pgsql-performance@postgresql.org; Thu, 19 Jan 2017 14:13:48 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.4/8.14.4) with ESMTP id v0JEDfrt016728; Thu, 19 Jan 2017 09:13:41 -0500 From: Tom Lane To: Gustavo Rezende Montesino cc: Clailson , phillip@couto.in, "pgsql-performance@postgresql.org" Subject: Re: Optimization inner join In-reply-to: <5880BDEA.9050804@trtsp.jus.br> References: <7ad1128e-7fdb-9976-823c-d4abdf554fa2@gmail.com> <497e3581-bcce-4efc-b281-6b17a93479c4@mtasv.net> <2cd4d430-54ad-4ab8-baae-b597c4a18c43@gmail.com> <5880BDEA.9050804@trtsp.jus.br> Comments: In-reply-to Gustavo Rezende Montesino message dated "Thu, 19 Jan 2017 11:23:54 -0200" MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-ID: <16726.1484835221.1@sss.pgh.pa.us> Content-Transfer-Encoding: quoted-printable Date: Thu, 19 Jan 2017 09:13:41 -0500 Message-ID: <16727.1484835221@sss.pgh.pa.us> X-Pg-Spam-Score: -5.1 (-----) 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 Gustavo Rezende Montesino writes: > Being the client in question, I would like to make a little remark: What= =20 > we thought could be optimized here at first is on the row estimate of=20 > the index scan; which could take null_frac into account. To put things=20 > into perspective, our similar case in production has a table with 6=20 > million lines where only 9.5k aren=C2=B4t null for the join field, an the= =20 > over-estimation is throwing away good plans (like ~150ms execution time)= =20 > in favor of pretty bad ones (~80s execution time). Please provide a concrete test case for that. AFAIK the null fraction should be accounted for in join size estimates. Here's a little test case showing that it is: regression=3D# create table t1 as select generate_series(1,1000000) as f1; SELECT 1000000 regression=3D# analyze t1; ANALYZE regression=3D# create table t2 as select generate_series(1,1000000) as f1; SELECT 1000000 regression=3D# analyze t2; ANALYZE regression=3D# explain select * from t1,t2 where t1.f1=3Dt2.f1; QUERY PLAN=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 ------------------------------------------------------------------------ Hash Join (cost=3D30832.00..70728.00 rows=3D1000000 width=3D8) Hash Cond: (t1.f1 =3D t2.f1) -> Seq Scan on t1 (cost=3D0.00..14425.00 rows=3D1000000 width=3D4) -> Hash (cost=3D14425.00..14425.00 rows=3D1000000 width=3D4) -> Seq Scan on t2 (cost=3D0.00..14425.00 rows=3D1000000 width=3D= 4) (5 rows) regression=3D# insert into t2 select null from generate_series(1,1000000); INSERT 0 1000000 regression=3D# analyze t2; ANALYZE regression=3D# explain select * from t1,t2 where t1.f1=3Dt2.f1; QUERY PLAN=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 ------------------------------------------------------------------------ Hash Join (cost=3D30832.00..95727.00 rows=3D1000000 width=3D8) Hash Cond: (t2.f1 =3D t1.f1) -> Seq Scan on t2 (cost=3D0.00..27862.00 rows=3D2000000 width=3D4) -> Hash (cost=3D14425.00..14425.00 rows=3D1000000 width=3D4) -> Seq Scan on t1 (cost=3D0.00..14425.00 rows=3D1000000 width=3D= 4) (5 rows) The join size estimate is still correct even though it knows there are many more rows in t2. As for inserting a not-null test at the scan level, I'm not exactly convinced that it's a win: regression=3D# \timing Timing is on. regression=3D# select count(*) from t1,t2 where t1.f1=3Dt2.f1; count=20=20 --------- 1000000 (1 row) Time: 562.914 ms regression=3D# select count(*) from t1,t2 where t1.f1=3Dt2.f1 and t2.f1 is = not null; count=20=20 --------- 1000000 (1 row) Time: 564.896 ms [ ftr, these times are best-of-three-trials ] It's possible that in the case where an explicit sort has to be inserted, reducing the amount of data passing through the sort would be worth doing; but in the general case that's unproven. regards, tom lane --=20 Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-performance