Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sVJl8-009B2a-M0 for pgsql-hackers@arkaria.postgresql.org; Sat, 20 Jul 2024 23:45:02 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1sVJAN-003GlN-4n for pgsql-hackers@arkaria.postgresql.org; Sat, 20 Jul 2024 23:07:03 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sVJAM-003GlF-P3 for pgsql-hackers@lists.postgresql.org; Sat, 20 Jul 2024 23:07:03 +0000 Received: from mail-ed1-x52e.google.com ([2a00:1450:4864:20::52e]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sVJAK-000cRJ-LS for pgsql-hackers@lists.postgresql.org; Sat, 20 Jul 2024 23:07:01 +0000 Received: by mail-ed1-x52e.google.com with SMTP id 4fb4d7f45d1cf-57cf8880f95so2104459a12.3 for ; Sat, 20 Jul 2024 16:06:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; t=1721516818; x=1722121618; darn=lists.postgresql.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=9IkL30BFrK/C3s8alQXYw+27x/G2WTtuYKpuTeP4Hwg=; b=VJP2dM/7Oe65tiQBYwmelM6PmUDrANxEKXG+c3KzU3MzNLbUitxHp0mEeezvTTNAhR KOqTIFW0ip12xkOJIs1S+aYZY4COoBx6MOC0F036gnaTeicMw8HeDBKJIUnrq0yfDDxk EzeSUo6SMTIbuiUem5EWKUaREp5Jmi6BKQrXBX4KKQrAq/VTOHCv/6pHhv1H0RK4tSZV vIXYLfTjvaS+y9VW3J406jRyc8GfqPIosPBUSUv3vTzhr0YvApx6Eht9OPLxCnTsqkfM f9TLG3nOxH2EVySEDRTV0BF7g2wDuaMx5+AeL92emeZOEF82NVx/oqeQp/GfeyJsiqRv BZrQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1721516818; x=1722121618; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=9IkL30BFrK/C3s8alQXYw+27x/G2WTtuYKpuTeP4Hwg=; b=HkLB7Qbj73sG2zPgkgrQA2/HMfIPlIU9YmX7pR28AfY3/4A7HUVtTbWqo330GMIOX8 7aDWsaSu4S7Aray4a3+KjIB+mV4tVvVIoCDmPsQE2HplQEQKQ4nVQ92hULHLf9ktz9io UmK7PljG6+XSl4YNgFxVLJYjAEOkdkv4qdOnINuPa14Hi48Kl0iUm/KJAdTvEa/HX1z3 cgAM8BVptUi9s5xbejfpgIjX8VKMLFAKmqPenSiXXQ16S2NrhVt75w2iTEIaftQNegXL KDHdLCc/mlYId595AzYPVAW5wCSSq3E89tpf0oDubYbMGIw3y1zF+e8qi7Ci2Pxaaqd7 zXjg== X-Forwarded-Encrypted: i=1; AJvYcCV5WQdSiRgVCYq7yc5NsM70inpqJx9oQfYyACOEixIT6hTJCy+od1mVThMigpUJToJ/vsOqUot2K9E3dQaGUds1shcfU/NFwiqf95dpQEeRGlE6 X-Gm-Message-State: AOJu0YzI2IGnpxqIVUC2RvAXANOE6BmhWuuyNHMbyTnWTmo7BluJFShU zw4tyj2H2fkpEiXDi7tR9lfr70pV4BfpwQfnsnUyTzl5Q2NezZSuvU1hU5KY6w== X-Google-Smtp-Source: AGHT+IFZYhylVTWZD3Aq9+xDd/FjR1Q4xaD7j3fQA+r2Wi76zaubnWrcQtQgN6s7ozDkJQsDaF9HlQ== X-Received: by 2002:a50:9f66:0:b0:5a2:8802:8e1b with SMTP id 4fb4d7f45d1cf-5a479a7067bmr1581748a12.22.1721516817862; Sat, 20 Jul 2024 16:06:57 -0700 (PDT) Received: from [10.137.0.18] (ip-86-49-229-30.bb.vodafone.cz. [86.49.229.30]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5a3e642b647sm2452319a12.55.2024.07.20.16.06.56 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 20 Jul 2024 16:06:57 -0700 (PDT) Message-ID: <8459b9bd-6248-4a43-a281-e40adb537242@enterprisedb.com> Date: Sun, 21 Jul 2024 01:06:55 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: Parallelize correlated subqueries that execute within each worker To: James Coleman , Robert Haas Cc: Akshat Jaimini , pgsql-hackers@lists.postgresql.org References: <170663138007.1131.9149309283833230346.pgcf@coridan.postgresql.org> Content-Language: en-US From: Tomas Vondra In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi, I was going through the "needs review" patches with no recent messages, trying to figure out what is needed to move them forward, and this one caught my eye because I commented on it before. And it's also a bit sad example, because it started in 2021 and is moving at glacier speed :-( I read through the thread, to understand how the design changed over time, and I like the current approach (proposed by Robert) much more than the initial idea of adding new flag next to parallel_safe etc. And in general the patch looks reasonably simple and clean, but my knowledge of PARAM intricacies is pretty much nil, so I'm hesitant to claim the patch is correct. And I'm not sure what exactly needs to happen to validate the approach :-( The regression tests currently fail, due to a different plan for one of the new queries in select_parallel. I guess it's due to some committed patch, and it looks like a sensible change, but I haven't looked closely. Also, I do get this warning when building with GCC 12.2.0 on Debian: clauses.c: In function ‘max_parallel_hazard_walker’: clauses.c:961:49: warning: ‘save_safe_param_ids’ may be used uninitialized [-Wmaybe-uninitialized] 961 | context->safe_param_ids = save_safe_param_ids; | ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~ clauses.c:943:29: note: ‘save_safe_param_ids’ was declared here 943 | List *save_safe_param_ids; | ^~~~~~~~~~~~~~~~~~~ It's harmless, the compiler simply does not realize the two blocks (where save_safe_param_ids is set and used) have exactly the same if conditions, but it's a bit confusing for people too. I was wondering if this could affect some queries in TPC-H, but the only query affected seems to be Q2 - where it helps, cutting the time in half, but Q2 is generally pretty fast / the expensive part was already parallelized quite well (i.e. the correlated subquery is fairly cheap). However, it's not difficult to construct a query where this helps a lot. If the correlated subquery does something expensive (e.g. aggregation of non-trivial amounts of data), this would help. So I wonder if e.g. TPC-DS would benefit from this more ... A couple review comments about the code: 1) new fields in max_parallel_hazard_context should have comments: + bool check_params; + Bitmapset **required_params; 2) Do we need both is_parallel_safe and is_parallel_safe_with_params? ISTM the main difference is the for() loop, so why not add an extra parameter to is_parallel_safe() and skip that loop if it's null? Or, if we worry about external code, keep is_parallel_safe_with_params() and define is_parallel_safe() as is_parallel_safe_with_params(...,NULL)? 3) Isn't it a bit weird that is_parallel_safe_with_params() actually sets check_params=false, which seems like it doesn't actually check parameters? I'm a bit confused / unsure if this is a bug or how it actually checks parameters. If it's correct, it may need a comment. 4) The only place setting check_params is max_parallel_hazard, which is called only for the whole Query from standard_planner(). But it does not set required_params - can't this be an issue if the pointer happens to be random garbage? 5) It probably needs a pgindent run, there's a bunch of rather long lines and those are likely to get wrapped and look weird. 6) Is the comment in max_parallel_hazard_walker() still accurate? It talks about PARAM_EXTERN and PARAM_EXEC, but the patch removes the PARAM_EXTERN check entirely. So maybe the comment needs updating? 7) I don't like the very complex if condition very much, it's hard to understand. I'd split that into two separate conditions, and add a short comment for each of them. I.e. instead of: if (param->paramkind != PARAM_EXEC || !(context->check_params || context->required_params != NULL)) return false; I'd do /* ... comment ... */ if (param->paramkind != PARAM_EXEC) return false; /* ... comment ... */ if (!(context->check_params || context->required_params != NULL)) return false; or something like that. regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company