@@ -457,23 +457,26 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor);
457457 <para>
458458 A multicolumn B-tree index can be used with query conditions that
459459 involve any subset of the index's columns, but the index is most
460- efficient when there are constraints on the leading (leftmost) columns.
461- The exact rule is that equality constraints on leading columns, plus
462- any inequality constraints on the first column that does not have an
463- equality constraint, will be used to limit the portion of the index
464- that is scanned. Constraints on columns to the right of these columns
465- are checked in the index, so they save visits to the table proper, but
466- they do not reduce the portion of the index that has to be scanned.
460+ efficient when there are equality constraints on the leading (leftmost) columns.
461+ B-Tree index scans can use the index skip scan strategy to generate
462+ equality constraints on prefix columns that were wholly omitted from the
463+ query predicate, as well as prefix columns whose values were constrained by
464+ inequality conditions.
467465 For example, given an index on <literal>(a, b, c)</literal> and a
468466 query condition <literal>WHERE a = 5 AND b >= 42 AND c < 77</literal>,
469467 the index would have to be scanned from the first entry with
470468 <literal>a</literal> = 5 and <literal>b</literal> = 42 up through the last entry with
471- <literal>a</literal> = 5. Index entries with <literal>c</literal> >= 77 would be
472- skipped, but they'd still have to be scanned through.
469+ <literal>a</literal> = 5. Intervening groups of index entries with
470+ <literal>c</literal> >= 77 would not need to be returned by the scan,
471+ and can be skipped over entirely by applying the skip scan strategy.
473472 This index could in principle be used for queries that have constraints
474473 on <literal>b</literal> and/or <literal>c</literal> with no constraint on <literal>a</literal>
475- — but the entire index would have to be scanned, so in most cases
476- the planner would prefer a sequential table scan over using the index.
474+ — but that approach is generally only taken when there are so few
475+ distinct <literal>a</literal> values that the planner expects the skip scan
476+ strategy to allow the scan to skip over most individual index leaf pages.
477+ If there are many distinct <literal>a</literal> values, then the entire
478+ index will have to be scanned, so in most cases the planner will prefer a
479+ sequential table scan over using the index.
477480 </para>
478481
479482 <para>
@@ -508,11 +511,15 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor);
508511 </para>
509512
510513 <para>
511- Multicolumn indexes should be used sparingly. In most situations,
512- an index on a single column is sufficient and saves space and time.
513- Indexes with more than three columns are unlikely to be helpful
514- unless the usage of the table is extremely stylized. See also
515- <xref linkend="indexes-bitmap-scans"/> and
514+ Multicolumn indexes should only be used when testing shows that they'll
515+ offer a clear advantage over simply using multiple single column indexes.
516+ Indexes with more than three columns can make sense, but only when most
517+ queries that make use of later columns also make use of earlier prefix
518+ columns. It's possible for B-Tree index scans to make use of <quote>skip
519+ scan</quote> optimizations with queries that omit a low cardinality
520+ leading prefix column, but this is usually much less efficient than a scan
521+ of an index without the extra prefix column. See <xref
522+ linkend="indexes-bitmap-scans"/> and
516523 <xref linkend="indexes-index-only-scans"/> for some discussion of the
517524 merits of different index configurations.
518525 </para>
@@ -669,9 +676,13 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);
669676 multicolumn index on <literal>(x, y)</literal>. This index would typically be
670677 more efficient than index combination for queries involving both
671678 columns, but as discussed in <xref linkend="indexes-multicolumn"/>, it
672- would be almost useless for queries involving only <literal>y</literal>, so it
673- should not be the only index. A combination of the multicolumn index
674- and a separate index on <literal>y</literal> would serve reasonably well. For
679+ would be less useful for queries involving only <literal>y</literal>. Just
680+ how useful might depend on how effective the B-Tree index skip scan
681+ optimization is; if <literal>x</literal> has no more than several hundred
682+ distinct values, skip scan will make searches for specific
683+ <literal>y</literal> values execute reasonably efficiently. A combination
684+ of a multicolumn index on <literal>(x, y)</literal> and a separate index on
685+ <literal>y</literal> might also serve reasonably well. For
675686 queries involving only <literal>x</literal>, the multicolumn index could be
676687 used, though it would be larger and hence slower than an index on
677688 <literal>x</literal> alone. The last alternative is to create all three
0 commit comments