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 1jZeH2-0006HH-Jy for pgsql-performance@arkaria.postgresql.org; Fri, 15 May 2020 17:37:28 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1jZeH1-0006Ma-I2 for pgsql-performance@arkaria.postgresql.org; Fri, 15 May 2020 17:37:27 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jZeH0-0006MM-GH for pgsql-performance@lists.postgresql.org; Fri, 15 May 2020 17:37:27 +0000 Received: from wout1-smtp.messagingengine.com ([64.147.123.24]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jZeGw-0007Jt-Vp for pgsql-performance@lists.postgresql.org; Fri, 15 May 2020 17:37:25 +0000 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.west.internal (Postfix) with ESMTP id 50478A90 for ; Fri, 15 May 2020 13:37:21 -0400 (EDT) Received: from imap36 ([10.202.2.86]) by compute4.internal (MEProxy); Fri, 15 May 2020 13:37:21 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=binarykeep.com; h=mime-version:message-id:in-reply-to:references:date:from:to :subject:content-type:content-transfer-encoding; s=mesmtp; bh=Zy Ssj7TjF7pARqww0qAu2VxtegcwcVS4EES8AEd9PeA=; b=RXGe7QwNMXbjw0Vfla 2O2ZFjw9jGXxQ2B0Sd5xyCYjYOcuTpF9IWBf5DLzrMaJm383y7+DgCAvjdGiCmMu U9+QWBzRQIXcHCj3JSvHokwJtPZ/CS6pOU1ZH9f5dgKEunm47COVa2MdZAFUviAu C6oRM2YLp1IyXYxJQTuP1QSuI= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm2; bh=ZySsj7TjF7pARqww0qAu2VxtegcwcVS4EES8AEd9P eA=; b=fjTmPGZir+8ZT4qxZ9xgEXQPzsSTMgLzwKEPVFnotcGK5e9XW6d7XELsj trqeHPo1E7wXl+rEihZJMkbhcxHNYP0jE+oXR2zNJSt8dmP8XO547YQ7Pnb0tg0a IYRup8UyeUMjgnqtanxr8EQbvHi6MpeQQoGft6SkZjT0Mm92l/EorcyBOCBCf1Vx 7oMWhyEvkEPiS2clHgt7Huxe4QmNglpWxjqbHnIJVyt7kC8mtcMQT4U9nQJex3Ag P9Bb+5ENvwEj+TOcCLS5rya8P6HOPKMJEqk++gkGt2v6eIiosyb+uyaNtyHzD//1 f5T0Ey00NpRDMk34EGWDZ6cO/nUkA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduhedrleekgdduudefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefofgggkfgjfhffhffvufgtgfesth hqredtreerjeenucfhrhhomhepfdforghtthhhvgifucfpvghlshhonhdfuceophhoshht ghhrvghssegsihhnrghrhihkvggvphdrtghomheqnecuggftrfgrthhtvghrnhepffdvgf ehieeiffekfffhhfduvdevudeuhefffefhveekieejudejheeghffhheeunecuvehluhhs thgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepphhoshhtghhrvghsse gsihhnrghrhihkvggvphdrtghomh X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id 7390E1880062; Fri, 15 May 2020 13:37:19 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.3.0-dev0-413-g750b809-fmstable-20200507v1 Mime-Version: 1.0 Message-Id: <808d494b-2d04-4811-a6f7-4fa3beab412e@www.fastmail.com> In-Reply-To: <9FFFC18C-C0C0-48A0-A61C-54381D322617@gmail.com> References: <677075a1-50bf-48b7-b7b6-ecebb8786741@www.fastmail.com> <9FFFC18C-C0C0-48A0-A61C-54381D322617@gmail.com> Date: Fri, 15 May 2020 10:36:58 -0700 From: "Matthew Nelson" To: pgsql-performance@lists.postgresql.org Subject: Re: Plan not skipping unnecessary inner join Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk But foo cannot be empty given the foreign key constraint on bar.foo_id. I suppose that explains the planner's behavior. While today's planner ca= n take a shortcut when it finds a unique constraint, it does not check f= or foreign key constraints matching the join condition? So the LEFT JOIN= simplification is possible but not the INNER JOIN simplification. Matthew On Wed, May 13, 2020, at 11:45 PM, David Wheeler wrote: > > Am I missing a situation where these joins could impact the result? >=20 > Yes it will impact the number of rows in the result. for example if fo= o=20 > is empty then postgres is required to return no results, regardless of= =20 > how many rows are in bar. This is why it can ignore the table in the=20= > left join >=20 > =E2=80=94 David >=20 > > On 14 May 2020, at 1:44 pm, Matthew Nelson = wrote: > >=20 > > I noticed something peculiar while optimizing complex views today. T= he query planner does not skip inner joins that, to my understanding, ca= n have no impact on the result. Am I missing a situation where these joi= ns could impact the result? > >=20 > > The following demonstrates the problem without the complex views. It= also demonstrates how the planner simplifies a LEFT JOIN in the same si= tuation. The left and right sides of an inner join could be swapped, obv= iously, but here I kept the unique constraint on the right. > >=20 > >=20 > >=20 > > CREATE TABLE foo ( > > id INTEGER PRIMARY KEY > > ); > >=20 > > CREATE TABLE bar ( > > foo_id INTEGER NOT NULL REFERENCES foo > > ); > >=20 > > -- This simplifies to SELECT COUNT(*) FROM bar; > > EXPLAIN SELECT COUNT(*) > > FROM bar > > LEFT JOIN foo ON bar.foo_id =3D foo.id; > >=20 > > -- This should simplify to SELECT COUNT(*) FROM bar WHERE foo_id IS = NOT NULL; > > -- The presence of a NOT NULL constraint on foo_id has no effect. > > EXPLAIN SELECT COUNT(*) > > FROM bar > > INNER JOIN foo ON bar.foo_id =3D foo.id; > >=20 > >=20 > >=20 > > QUERY PLAN =20 > > ------------------------------------------------------------- > > Aggregate (cost=3D38.25..38.26 rows=3D1 width=3D8) > > -> Seq Scan on bar (cost=3D0.00..32.60 rows=3D2260 width=3D0) > > (2 rows) > >=20 > > QUERY PLAN = =20 > > --------------------------------------------------------------------= ----- > > Aggregate (cost=3D111.57..111.58 rows=3D1 width=3D8) > > -> Hash Join (cost=3D67.38..105.92 rows=3D2260 width=3D0) > > Hash Cond: (bar.foo_id =3D foo.id) > > -> Seq Scan on bar (cost=3D0.00..32.60 rows=3D2260 width=3D= 4) > > -> Hash (cost=3D35.50..35.50 rows=3D2550 width=3D4) > > -> Seq Scan on foo (cost=3D0.00..35.50 rows=3D2550 w= idth=3D4) > > (6 rows) > >=20 > > version = =20 > > --------------------------------------------------------------------= ----------------------------------------------- > > PostgreSQL 12.2 on x86_64-apple-darwin19.4.0, compiled by Apple clan= g version 11.0.3 (clang-1103.0.32.59), 64-bit > > (1 row) > >=20 > >=20 >=20 >