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 1uoAgs-00HKfw-3U for pgsql-hackers@arkaria.postgresql.org; Tue, 19 Aug 2025 00:59:07 +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 1uoAgr-004E0i-AY for pgsql-hackers@arkaria.postgresql.org; Tue, 19 Aug 2025 00:59:05 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1uoAgq-004E0Z-TH for pgsql-hackers@lists.postgresql.org; Tue, 19 Aug 2025 00:59:05 +0000 Received: from mail-pl1-x62c.google.com ([2607:f8b0:4864:20::62c]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1uoAgo-000YvT-2b for pgsql-hackers@lists.postgresql.org; Tue, 19 Aug 2025 00:59:04 +0000 Received: by mail-pl1-x62c.google.com with SMTP id d9443c01a7336-244581cc971so55882765ad.2 for ; Mon, 18 Aug 2025 17:59:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1755565142; x=1756169942; darn=lists.postgresql.org; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:from:to:cc:subject:date:message-id:reply-to; bh=J7um9H1O4XMjF8/LkZqEBG3SVMuEsUKv6Zush7dSs2U=; b=edjZJv18e3ZO5kTPGeZvw1UWXVfXufaUclwBmR8eZZZSWYAByu44ohpzgOiIbUubAI PKVKBNJbOTm1UGQUgrB4WBOjx6m+G16DyX3V8vg61lbqAme974KShK36vz6QGaFYrWz8 YAmI+lubqLKfvOD/ZiF/3CeScOjBS1K2dc55YAEbG+hEx6fzOxkKX32Hb1bXtrh0wfPl Gj+LMkHjFTj+ba5Hfw4zqPZNVWSvGGVE9wGTs02J9ht3+CiC6ETYxa7BeKyivRiNasie uSB92ueohVpCaV9/BlClqn1mMM9re8Obs+vC4/013qk8Uhhsq0TKOWjcXVoZcI/uaElg OnSA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1755565142; x=1756169942; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=J7um9H1O4XMjF8/LkZqEBG3SVMuEsUKv6Zush7dSs2U=; b=NAv0EmsHM/kO/KBztpQAktatMkrbDbSlL/+0cJc3/0jmPArfzJ/MxX0jFI6oFxAOEK luTVzPhCEeB0wzP8cX5k4MptOrAMq0WaEi0fmGzX4cX2eAMsAtrqB/YJH/JBdSXNaKeY 7tPhE2M9j/k8m4JP1NDxPq/mflVDmeIoUdVjGRqsDjTVDr2dF8je4CSJ9qudpwcBpg7M d1cwDcDzEkPDLvvlRSzmgpJCADAHIyEsoFOCeg8HQAEdvEV3+OvbaOhkWHlO6f/jqeWG m4oDa86KyRumje7e4wGsT0QAUkTOuYGYeKUx3kYRucLP8hGYxpA0vg2cfhJKlp8zbJtQ RqIA== X-Gm-Message-State: AOJu0YxRTnpBDvwubdYouWknM6oDcwcdC8DUjwKRvvB9EqBL0T6ot9NA YKJdbneXbhMeExW68ZJSXKZpveOkqAeuYj1mI1frh3MOwx+yXfU3tghN X-Gm-Gg: ASbGncsMIZ7MA2+vJSdnlqCFyIeP4Vw1m2OOgpUOTtwAb2o1ZUz4YDqh+s4eGdCmTQB ML05NMk8FoRE+tL9gwmwNoI365Tlmg8i+y76G+QrlAuE/ohosO/VNS+dxhJr8gejXk42oC0ETtl eBaIqV5nPNK8BaSCB5nwXrCAlAIamFzgkpeXoWlkKDpZ+vy3pfXBtZkq2gzshiHQA8CTbPScCix hS/7GvkxNkY+Cfux8gv+4hdoeMzBiQg9wZLVR5INDIFoZ4buaPEbQjHtzvBteKe2FRN6Uvz/PNx C3FMA0ib23Ct0PgcBANFvilau/cRyA/WMOXZ2Gd/B109LmeZhh84tY/Fs3OvaSW+qAwH9l+QaPg s3dOd4/3zta6c65Dxy8hvQ4w1eLtn0e+6 X-Google-Smtp-Source: AGHT+IHNKi1e1DfrOCJasqczVsjHMOIrHilu0fdrw+HG2UI/QPoYtZnXxeW8hMvVTrcBJVehEUmjbg== X-Received: by 2002:a17:903:1b64:b0:240:8ec:fe2 with SMTP id d9443c01a7336-245e02aa63dmr8819445ad.4.1755565142246; Mon, 18 Aug 2025 17:59:02 -0700 (PDT) Received: from smtpclient.apple ([142.171.105.12]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2446d59a188sm91907345ad.162.2025.08.18.17.59.00 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Aug 2025 17:59:01 -0700 (PDT) From: Chao Li Message-Id: <659B2B36-C0FE-4642-921D-E7120E838891@gmail.com> Content-Type: multipart/alternative; boundary="Apple-Mail=_0F250CA4-2D85-40B6-8CB0-7A2FCCDA83E1" Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3826.700.81\)) Subject: Re: Improve hash join's handling of tuples with null join keys Date: Tue, 19 Aug 2025 08:58:47 +0800 In-Reply-To: <463296.1755553046@sss.pgh.pa.us> Cc: pgsql-hackers@lists.postgresql.org To: Tom Lane References: <3061845.1746486714@sss.pgh.pa.us> <496221.1748882849@sss.pgh.pa.us> <175507656113.993.1381684440543440253.pgcf@coridan.postgresql.org> <544D7C83-CECE-44E7-B5D7-530E9318D231@gmail.com> <616751.1755276726@sss.pgh.pa.us> <5C5EE031-F086-4353-A17A-DA563CD24DDD@gmail.com> <463296.1755553046@sss.pgh.pa.us> X-Mailer: Apple Mail (2.3826.700.81) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --Apple-Mail=_0F250CA4-2D85-40B6-8CB0-7A2FCCDA83E1 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii > On Aug 19, 2025, at 05:37, Tom Lane wrote: >>=20 >=20 > Yeah, we could make multi-batch PHJ do this differently from the other > cases, but I don't want to go there: too much complication and risk of > bugs for what is a purely hypothetical performance issue. Besides > which, if the join is large enough to be worth worrying over, it's > most likely taking that code path anyhow. >=20 >=20 >> We can simply added a new flag to HashTable, say named = skip_building_hash. Upon right join (join to the hash side), and outer = table is empty, set the flag to true, then in the = MultiExecPrivateHash(), if skip_building_hash is true, directly put all = tuples into node->null_tuple_store without building a hash table. >> Then in ExecHashJoinImpl(), after "(void) MultiExecProcNode()" is = called, if hashtable->skip_building_hash is true, directly set = node->hj_JoinState =3D HJ_FILL_INNER_NULL_TUPLES. >=20 > I'm not excited about this idea either. It's completely abusing the > data structure, because the "null_tuple_store" is now being used for > tuples that (probably) don't have null join keys. The fact that you > could cram it in with not very many lines of code does not mean that > the result will be understandable or maintainable --- and certainly, > hash join is on the hairy edge of being too complicated already. >=20 > regards, tom lane Thanks for the explanation. Then these two comments are resolved. -- Chao Li (Evan) HighGo Software Co., Ltd. https://www.highgo.com/ --Apple-Mail=_0F250CA4-2D85-40B6-8CB0-7A2FCCDA83E1 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=us-ascii

On Aug 19, 2025, at 05:37, Tom Lane = <tgl@sss.pgh.pa.us> wrote:


Yeah, we could make multi-batch PHJ = do this differently from the other
cases, but I don't want to go = there: too much complication and risk of
bugs for what is a purely = hypothetical performance issue.  Besides
which, if the join is = large enough to be worth worrying over, it's
most likely taking that = code path anyhow.


We can simply = added a new flag to HashTable, say named skip_building_hash. Upon right = join (join to the hash side), and outer table is empty, set the flag to = true, then in the MultiExecPrivateHash(), if skip_building_hash is true, = directly put all tuples into node->null_tuple_store without building = a hash table.
Then in ExecHashJoinImpl(), after "(void) = MultiExecProcNode()" is called, if hashtable->skip_building_hash is = true, directly set node->hj_JoinState =3D = HJ_FILL_INNER_NULL_TUPLES.

I'm not excited about = this idea either.  It's completely abusing the
data structure, = because the "null_tuple_store" is now being used for
tuples that = (probably) don't have null join keys.  The fact that you
could = cram it in with not very many lines of code does not mean that
the = result will be understandable or maintainable --- and certainly,
hash = join is on the hairy edge of being too complicated already.

regards, = tom lane

Thanks = for the explanation. Then these two comments are = resolved.

--
Chao Li (Evan)
HighGo Software = Co., Ltd.
https://www.highgo.com/




= --Apple-Mail=_0F250CA4-2D85-40B6-8CB0-7A2FCCDA83E1--