Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jmJVd-0005qO-9v for pgsql-performance@arkaria.postgresql.org; Fri, 19 Jun 2020 16:04:53 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1jmJVc-0005Ky-7x for pgsql-performance@arkaria.postgresql.org; Fri, 19 Jun 2020 16:04:52 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jmJVc-0005Kr-1I for pgsql-performance@lists.postgresql.org; Fri, 19 Jun 2020 16:04:52 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jmJVZ-0005xR-T6 for pgsql-performance@postgresql.org; Fri, 19 Jun 2020 16:04:51 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 05JG4lRs1666227; Fri, 19 Jun 2020 12:04:47 -0400 From: Tom Lane To: "Benjamin Coutu" cc: pgsql-performance@postgresql.org Subject: Re: Unclamped row estimates whith OR-ed subplans In-reply-to: <20200619151232.7F3285FB26@mx.zeyos.com> References: <20200619151232.7F3285FB26@mx.zeyos.com> Comments: In-reply-to "Benjamin Coutu" message dated "Fri, 19 Jun 2020 17:12:31 +0200" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <1666225.1592582687.1@sss.pgh.pa.us> Content-Transfer-Encoding: quoted-printable Date: Fri, 19 Jun 2020 12:04:47 -0400 Message-ID: <1666226.1592582687@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk "Benjamin Coutu" writes: > please consider the following SQL query: > SELECT * FROM "transactions" WHERE = > "account" IN (SELECT "ID" FROM "accounts" WHERE "name" ~~* '%test%') OR > "contract" IN (SELECT "ID" FROM "contracts" WHERE "name" ~~* '%test%') > This yields the following plan on Postgres 11: > Seq Scan on transactions (cost=3D67.21..171458.03 rows=3D1301316 width=3D= 1206) > Filter: ((hashed SubPlan 1) OR (hashed SubPlan 2)) > SubPlan 1 > -> Bitmap Heap Scan on accounts (cost=3D33.36..61.16 rows=3D46 wid= th=3D4) > Recheck Cond: ((name)::text ~~* '%test%'::text) > -> Bitmap Index Scan on s_accounts (cost=3D0.00..33.35 rows=3D= 46 width=3D0) > Index Cond: ((name)::text ~~* '%test%'::text) > SubPlan 2 > -> Seq Scan on contracts (cost=3D0.00..5.93 rows=3D5 width=3D4) > Filter: ((name)::text ~~* '%test%'::text) > So the where clause of this query has just two subplans OR-ed together, = one is estimated to yield 46 rows and one is estimated to yield 5 rows. > I'd expect the total rows for the seqscan to be estimated at 46 then, fo= llowing the logic that rows_seqscan =3D max(rows_subplan1, rows_subplan2).= As you can see, the optimizer estimates a whopping 1301316 rows instead. No. The subplan estimates are for the number of rows produced by one execution of the subplan, ie the numbers of "accounts" or "contracts" rows that match those inner WHERE conditions. This has very little a-priori relationship to the number of "transactions" rows that will satisfy the outer WHERE condition. If we knew that transactions.account and transactions.contract were unique columns, then we might be able to say that there shouldn't be more than one outer match per subplan result row ... but you didn't say that, and it seems unlikely. (Having said that, I think that the estimates for these cases very possibly are quite stupid. But that doesn't mean that 46+5 would be the right answer.) regards, tom lane