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 1vIKCZ-00478Q-JD for pgsql-performance@arkaria.postgresql.org; Mon, 10 Nov 2025 05:12:27 +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 1vIKCY-00E39b-9b for pgsql-performance@arkaria.postgresql.org; Mon, 10 Nov 2025 05:12:26 +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 1vIKCX-00E39R-Uu for pgsql-performance@lists.postgresql.org; Mon, 10 Nov 2025 05:12:25 +0000 Received: from mail-lj1-f182.google.com ([209.85.208.182]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vIKCV-006vHw-0Q for pgsql-performance@lists.postgresql.org; Mon, 10 Nov 2025 05:12:25 +0000 Received: by mail-lj1-f182.google.com with SMTP id 38308e7fff4ca-376466f1280so34459681fa.0 for ; Sun, 09 Nov 2025 21:12:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762751542; x=1763356342; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=cTn0r5BKDj7UbsooOPGplj3zBr8Dc9fXeaCBCQ7fzb0=; b=ZYDBwvu4WZjr133wzjHQfoKzyF3uInllDe68LCKge41nHdZ2NrtQxjydxSlkdHOab1 Ikb47DgX4MPkLaScGfaw7NdCiS7PBSgfEgf/iizOceK++u1k4EIsWHhAz9pnCBcjxMGf bagmiybWjRSB6YtGXgm++9sIkxTjejEoeaGwt3/hODAcfE3eQk3FFMkJf3j5wrp9OSkf n9i9X5oaFWLgGluWG5Abpv3wzCIx6wZg/czLHgtOb7vCgZ8GiKZUMPPdPGIJ8asPMDvb xRGyNGA77ubOQzKWuRpC1641RZ78LDo83p9u8xqs3CM7IJkfj8TcYXm7OP9JWMxF436p wx0A== X-Gm-Message-State: AOJu0Yx1/VDA7RaAljhWCKd5bgEdYw3AkMUHNPVIyXxHIRwo4kARRZkK DPjzWR/IffhnDLBW5S0+vVvhhEnHMqixnSHLuLS9Yf7EMQNE1yiCzSxk42Gk+pp+FEVXnqLdKi7 UE4Qw3NzsYGhT+W7o0ernw/dCjb+uYLg= X-Gm-Gg: ASbGncsNAqZFvjlicwCz+/loY6w7Ph6TBPYoVh5BXK5s1BSPQibo1buVsVhpnW3aA7O sVu9W1dtQQenuqY/1y8+yFpZaLFqvBEO7AQVNwXvQA5xBWf1EoaS8ZAPbR1ArAwovkPZBsgKqDB wodRs9PSCwFI44rMTyGBnq3UZm5JnOPYLm+82crKOhrvq3JiOBU/yjBfJ+n+Y/MWfYAHEXRGebI QD+NbyFpM+S3hLG1ui489jFuiNalYeinaOl3jq9YuTDId6hdjZ+x3lVFMxoRNE2oqfwsH4= X-Google-Smtp-Source: AGHT+IFEJksHOSnlh0kf3xbV0ITUpIum0SUKO6J1pciQPImDaQYXzrlMJb05GtV+6RjdQDKerRf/phC0yk0TK+WlKmo= X-Received: by 2002:a05:6512:3ca6:b0:594:26be:85ab with SMTP id 2adb3069b0e04-5945f165122mr2096403e87.7.1762751541420; Sun, 09 Nov 2025 21:12:21 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Vitalii Tymchyshyn Date: Sun, 9 Nov 2025 21:12:09 -0800 X-Gm-Features: AWmQ_bkSb-yWzpeVbhb2neFE9Nm9LVtJiEeSkl7aprTX3CpczC3H6y27a-L493g Message-ID: Subject: Re: Multicolumn index scan efficiency To: Peter Geoghegan Cc: pgsql-performance@lists.postgresql.org Content-Type: multipart/alternative; boundary="00000000000074285206433693cf" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000074285206433693cf Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Thank you so much for both clarifying and fixing it! In our case (FYI, this is from http://github.com/cdapio/cdap) a lot of users have just a single namespace, so it effectively means scanning till the end of the index. We'll fix https://github.com/cdapio/cdap/blob/develop/cdap-data-fabric/src/main/java/= io/cdap/cdap/spi/data/sql/PostgreSqlStructuredTable.java to detect equality scan prefixes and make corresponding SQL. That would fix it for all postgres versions. Best regards, Vitalii Tymchyshyn =D0=BD=D0=B4, 9 =D0=BB=D0=B8=D1=81=D1=82. 2025=E2=80=AF=D1=80. =D0=BE 20:21= Peter Geoghegan =D0=BF=D0=B8=D1=88=D0=B5: > On Sun, Nov 9, 2025 at 9:44=E2=80=AFPM Vitalii Tymchyshyn wr= ote: > > I am wondering about 2 things: > > 1) Does anyone know which specific change / version made it fast? > > 2) What was the proper way to do a range index scan like WHERE (a,b,c) > between (x1,y1,z1) and (x2,y2,z2) before the improvement. > > Note that my tests can mostly be rewritten as equality at least for som= e > columns (and this is what we'll do), but sometimes we do need a range sca= n > like above, so understanding it would be important. Also I am curious :). > > This improvement you're seeing here is down to work in commit > bd3f59fd. The short version is that the way we used to decide when a > condition like "WHERE (a,b,c) <=3D (x2,y2,z2)" was needlessly > conservative. If there were many "a" values equal to x2, we'd have to > scan the index until we got to the next distinct/non-equal "a" value > -- without realizing that we're already past the point where there > cannot possibly be any more matches. > > See the discussion on this thread which complained about the problem, > particularly my response to the complaint: > > > https://www.postgresql.org/message-id/flat/CAH2-WzmLREy6r68A6SEHXnstg01kN= s1HiQtOvSO5cTvWuaducw%40mail.gmail.com#62e393ac8bbf06f0f73598ba2ceeab69 > > -- > Peter Geoghegan > --00000000000074285206433693cf Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Thank you so much for both clarifying and= fixing it!
In our case (FYI, this=C2=A0is from=C2=A0http://github.com/cdapio/cdap) a lot of users h= ave just a single namespace, so it effectively means scanning till the end = of the index.
We'll fix=C2=A0https://github.com/cdapio/cdap/blob/de= velop/cdap-data-fabric/src/main/java/io/cdap/cdap/spi/data/sql/PostgreSqlSt= ructuredTable.java to detect equality scan prefixes and make correspond= ing SQL. That would fix it for all postgres versions.=C2=A0

<= /div>
Best regards, Vitalii Tymchyshyn

=D0= =BD=D0=B4, 9 =D0=BB=D0=B8=D1=81=D1=82. 2025=E2=80=AF=D1=80. =D0=BE 20:21 Pe= ter Geoghegan <pg@bowt.ie> =D0=BF= =D0=B8=D1=88=D0=B5:
On Sun, Nov 9, 2025 at 9:44=E2=80=AFPM Vitalii Tymchyshyn <vit@tym.im> wrote:
> I am wondering about 2 things:
> 1) Does anyone know which specific change / version made it fast?
> 2) What was the proper way to do a range index scan like WHERE (a,b,c)= between (x1,y1,z1) and (x2,y2,z2) before the improvement.
> Note that my tests can mostly be rewritten as equality at least for so= me columns (and this is what we'll do), but sometimes we do need a rang= e scan like above, so understanding it would be important. Also I am curiou= s :).

This improvement you're seeing here is down to work in commit
bd3f59fd. The short version is that the way we used to decide when a
condition like "WHERE (a,b,c) <=3D (x2,y2,z2)" was needlessly<= br> conservative. If there were many "a" values equal to x2, we'd= have to
scan the index until we got to the next distinct/non-equal "a" va= lue
-- without realizing that we're already past the point where there
cannot possibly be any more matches.

See the discussion on this thread which complained about the problem,
particularly my response to the complaint:

https://www.postgresql.org/mess= age-id/flat/CAH2-WzmLREy6r68A6SEHXnstg01kNs1HiQtOvSO5cTvWuaducw%40mail.gmai= l.com#62e393ac8bbf06f0f73598ba2ceeab69

--
Peter Geoghegan
--00000000000074285206433693cf--