aboutsummaryrefslogtreecommitdiff
path: root/doc/src
diff options
context:
space:
mode:
authorAlexander Korotkov <akorotkov@postgresql.org>2024-04-08 01:27:28 +0300
committerAlexander Korotkov <akorotkov@postgresql.org>2024-04-08 01:27:52 +0300
commit72bd38cc99a15da6f97373fae98027c908c398ea (patch)
tree090cdaccbab7286e709f6ebe9a4ddc6142e936f8 /doc/src
parent75a47b6a0dc4a235307e1acd1a6b3845cb881e55 (diff)
downloadpostgresql-72bd38cc99a15da6f97373fae98027c908c398ea.tar.gz
postgresql-72bd38cc99a15da6f97373fae98027c908c398ea.zip
Transform OR clauses to ANY expression
Replace (expr op C1) OR (expr op C2) ... with expr op ANY(ARRAY[C1, C2, ...]) on the preliminary stage of optimization when we are still working with the expression tree. Here Cn is a n-th constant expression, 'expr' is non-constant expression, 'op' is an operator which returns boolean result and has a commuter (for the case of reverse order of constant and non-constant parts of the expression, like 'Cn op expr'). Sometimes it can lead to not optimal plan. This is why there is a or_to_any_transform_limit GUC. It specifies a threshold value of length of arguments in an OR expression that triggers the OR-to-ANY transformation. Generally, more groupable OR arguments mean that transformation will be more likely to win than to lose. Discussion: https://postgr.es/m/567ED6CA.2040504%40sigaev.ru Author: Alena Rybakina <lena.ribackina@yandex.ru> Author: Andrey Lepikhov <a.lepikhov@postgrespro.ru> Reviewed-by: Peter Geoghegan <pg@bowt.ie> Reviewed-by: Ranier Vilela <ranier.vf@gmail.com> Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com> Reviewed-by: Robert Haas <robertmhaas@gmail.com> Reviewed-by: Jian He <jian.universality@gmail.com>
Diffstat (limited to 'doc/src')
-rw-r--r--doc/src/sgml/config.sgml57
1 files changed, 57 insertions, 0 deletions
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index d8e1282e128..ac945ca4d19 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -6304,6 +6304,63 @@ SELECT * FROM parent WHERE key = 2400;
</listitem>
</varlistentry>
+ <varlistentry id="guc-or-to-any-transform-limit" xreflabel="or_to_any_transform_limit">
+ <term><varname>or_to_any_transform_limit</varname> (<type>boolean</type>)
+ <indexterm>
+ <primary><varname>or_to_any_transform_limit</varname> configuration parameter</primary>
+ </indexterm>
+ </term>
+ <listitem>
+ <para>
+ Sets the minimum length of arguments in an <literal>OR</literal>
+ expression exceeding which planner will try to lookup and group
+ multiple similar <literal>OR</literal> expressions to
+ <literal>ANY</literal> (<xref linkend="functions-comparisons-any-some"/>)
+ expressions. The grouping technique of this transformation is based
+ on the equivalence of variable sides. One side of such an expression
+ must be a constant clause, and the other must contain a variable
+ clause. The default value is <literal>5</literal>. The value of
+ <literal>-1</literal> completely disables the transformation.
+ </para>
+ <para>
+ The advantage of this <literal>OR-to-ANY</literal> transformation is
+ faster query planning and execution. In certain cases, this
+ transformation also leads to more effective plans containing
+ a single index scan instead of multiple bitmap scans. However, it
+ may also cause a planning regression when distinct
+ <literal>OR</literal> arguments are better to match to distinct indexes.
+ This may happen when they have different matching partial indexes or
+ have different distributions of other columns used in the query.
+ Generally, more groupable <literal>OR</literal> arguments mean that
+ transformation will be more likely to win than to lose.
+ </para>
+ <para>
+ For example, this query has its set of five <literal>OR</literal>
+ expressions transformed to <literal>ANY</literal> with the default
+ value of <varname>or_to_any_transform_limit</varname>. But not with
+ the increased value.
+<programlisting>
+# EXPLAIN SELECT * FROM tbl WHERE key = 1 OR key = 2 OR key = 3 OR key = 4 OR key = 5;
+ QUERY PLAN
+-----------------------------------------------------
+ Seq Scan on tbl (cost=0.00..51.44 rows=64 width=4)
+ Filter: (key = ANY ('{1,2,3,4,5}'::integer[]))
+(2 rows)
+
+# SET or_to_any_transform_limit = 6;
+SET
+
+# EXPLAIN SELECT * FROM tbl WHERE key = 1 OR key = 2 OR key = 3 OR key = 4 OR key = 5;
+ QUERY PLAN
+---------------------------------------------------------------------------
+ Seq Scan on tbl (cost=0.00..67.38 rows=63 width=4)
+ Filter: ((key = 1) OR (key = 2) OR (key = 3) OR (key = 4) OR (key = 5))
+(2 rows)
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry id="guc-plan-cache-mode" xreflabel="plan_cache_mode">
<term><varname>plan_cache_mode</varname> (<type>enum</type>)
<indexterm>