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 1janmk-0005DN-Q1 for pgsql-performance@arkaria.postgresql.org; Mon, 18 May 2020 21:58:58 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1janmj-0006pi-Ls for pgsql-performance@arkaria.postgresql.org; Mon, 18 May 2020 21:58:57 +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 1janmj-0006pa-ER for pgsql-performance@lists.postgresql.org; Mon, 18 May 2020 21:58:57 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1janmc-00048W-QT for pgsql-performance@lists.postgresql.org; Mon, 18 May 2020 21:58:56 +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 04ILwmgr019696; Mon, 18 May 2020 17:58:48 -0400 From: Tom Lane To: A Guy Named Ryan cc: Pavel Stehule , Pgsql Performance Subject: Re: Execution time from >1s -> 80m+ when extra columns added in SELECT for sub-query In-reply-to: References: Comments: In-reply-to A Guy Named Ryan message dated "Mon, 18 May 2020 13:49:39 -0700" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <19694.1589839128.1@sss.pgh.pa.us> Date: Mon, 18 May 2020 17:58:48 -0400 Message-ID: <19695.1589839128@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk A Guy Named Ryan writes: > Why would the planner switch plans so drastically given that all I'm > doing is including a few extra columns in the subselect, particularly > when those columns are discarded by the super? parent? subselect The problem is that the columns you're adding *don't belong to that table*. Per your schema dump, jtemp1c37l3b_baseline_windows_with_collections only contains the columns person_id and uuid. So when you write SELECT "uuid" AS "uuid", CAST(NULL AS float) AS "drug_amount", CAST(NULL AS text) AS "drug_amount_units", CAST(NULL AS bigint) AS "drug_days_supply", CAST(NULL AS text) AS "drug_name", CAST(NULL AS float) AS "drug_quantity", CAST(NULL AS integer) AS "window_id", "person_id" AS "person_id", "criterion_id" AS "criterion_id", "criterion_table" AS "criterion_table", "criterion_domain" AS "criterion_domain", "start_date" AS "start_date", "end_date" AS "end_date" FROM "jigsaw_temp"."jtemp1c37l3b_baseline_windows_with_collections" those are the only two columns that are "legitimately" part of that bottom sub-select, and the others are outer references to jtemp1c37l3b_baseline_windows_after_inclusion. That's legal per SQL, but it makes the EXISTS into a correlated sub-select, which is something we can't turn into a semijoin. Indeed, the unreferenced columns do get thrown away later, but that doesn't happen until well past the point where the join restructuring decisions are made (and there are good reasons for that ordering of operations). Basically I'd write this off as "broken SQL code generator". If it doesn't understand the difference between a local reference and an outer reference, you shouldn't be letting it near your database. That sort of fundamental misunderstanding often leads to incorrect query results, never mind whether the query is fast or not. regards, tom lane