mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Support index-only scans using the visibility map to avoid heap fetches.
When a btree index contains all columns required by the query, and the visibility map shows that all tuples on a target heap page are visible-to-all, we don't need to fetch that heap page. This patch depends on the previous patches that made the visibility map reliable. There's a fair amount left to do here, notably trying to figure out a less chintzy way of estimating the cost of an index-only scan, but the core functionality seems ready to commit. Robert Haas and Ibrar Ahmed, with some previous work by Heikki Linnakangas.
This commit is contained in:
@ -476,6 +476,13 @@
|
||||
<entry>Does the access method support multicolumn indexes?</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>amcanreturn</structfield></entry>
|
||||
<entry><type>bool</type></entry>
|
||||
<entry></entry>
|
||||
<entry>Can the access method return the contents of index entries?</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>amoptionalkey</structfield></entry>
|
||||
<entry><type>bool</type></entry>
|
||||
|
@ -2404,6 +2404,22 @@ SET ENABLE_SEQSCAN TO OFF;
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry id="guc-enable-indexonlyscan" xreflabel="enable_indexonlyscan">
|
||||
<term><varname>enable_indexonlyscan</varname> (<type>boolean</type>)</term>
|
||||
<indexterm>
|
||||
<primary>index-only scan</primary>
|
||||
</indexterm>
|
||||
<indexterm>
|
||||
<primary><varname>enable_indexonlyscan</> configuration parameter</primary>
|
||||
</indexterm>
|
||||
<listitem>
|
||||
<para>
|
||||
Enables or disables the query planner's use of index-only-scan plan
|
||||
types. The default is <literal>on</>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry id="guc-enable-material" xreflabel="enable_material">
|
||||
<term><varname>enable_material</varname> (<type>boolean</type>)</term>
|
||||
<indexterm>
|
||||
@ -6353,7 +6369,7 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1)
|
||||
<row>
|
||||
<entry>
|
||||
<option>-fb</option>, <option>-fh</option>, <option>-fi</option>,
|
||||
<option>-fm</option>, <option>-fn</option>,
|
||||
<option>-fm</option>, <option>-fn</option>, <option>-fo</option>,
|
||||
<option>-fs</option>, <option>-ft</option>
|
||||
</entry>
|
||||
<entry>
|
||||
@ -6362,6 +6378,7 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1)
|
||||
<literal>enable_indexscan = off</>,
|
||||
<literal>enable_mergejoin = off</>,
|
||||
<literal>enable_nestloop = off</>,
|
||||
<literal>enable_indexonlyscan = off</>,
|
||||
<literal>enable_seqscan = off</>,
|
||||
<literal>enable_tidscan = off</>
|
||||
</entry>
|
||||
|
@ -134,6 +134,11 @@
|
||||
<structfield>amsearchnulls</structfield>, indicating that it supports
|
||||
<literal>IS NULL</> and <literal>IS NOT NULL</> clauses as search
|
||||
conditions.
|
||||
An index method can also set <structfield>amcanreturn</structfield>,
|
||||
indicating that it can support <firstterm>index-only scans</> by returning
|
||||
the indexed column values for an index entry in the form of an IndexTuple.
|
||||
(An example of an index AM that cannot do this is hash, which stores only
|
||||
the hash values not the original data.)
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
@ -385,6 +390,18 @@ amgettuple (IndexScanDesc scan,
|
||||
callers.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If the access method supports index-only scans (i.e.,
|
||||
<structfield>amcanreturn</structfield> is TRUE in its <structname>pg_am</>
|
||||
row), then on success it must also check
|
||||
<literal>scan->xs_want_itup</>, and if that is true it should return
|
||||
the original indexed data for the index entry, in the form of an
|
||||
<structname>IndexTuple</> stored at <literal>scan->xs_itup</>. However,
|
||||
it is permissible for the access method to sometimes fail to provide this
|
||||
data, in which case it must set <literal>scan->xs_itup</> to NULL. That
|
||||
will result in a regular heap fetch occurring.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The <function>amgettuple</> function need only be provided if the access
|
||||
method supports <quote>plain</> index scans. If it doesn't, the
|
||||
@ -581,6 +598,15 @@ amrestrpos (IndexScanDesc scan);
|
||||
deleted.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If the index stores the original indexed data values (and not some lossy
|
||||
representation of them), it is useful to support index-only scans, in
|
||||
which the index returns the actual data not just the TID of the heap tuple.
|
||||
This will only work if the visibility map shows that the TID is on an
|
||||
all-visible page; else the heap tuple must be visited anyway to check
|
||||
MVCC visibility. But that is no concern of the access method's.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Instead of using <function>amgettuple</>, an index scan can be done with
|
||||
<function>amgetbitmap</> to fetch all tuples in one call. This can be
|
||||
@ -593,7 +619,11 @@ amrestrpos (IndexScanDesc scan);
|
||||
supported. Secondly, the tuples are returned in a bitmap which doesn't
|
||||
have any specific ordering, which is why <function>amgetbitmap</> doesn't
|
||||
take a <literal>direction</> argument. (Ordering operators will never be
|
||||
supplied for such a scan, either.) Finally, <function>amgetbitmap</>
|
||||
supplied for such a scan, either.)
|
||||
Also, there is no provision for index-only scans with
|
||||
<function>amgetbitmap</>, since there is no way to return the contents of
|
||||
index tuples.
|
||||
Finally, <function>amgetbitmap</>
|
||||
does not guarantee any locking of the returned tuples, with implications
|
||||
spelled out in <xref linkend="index-locking">.
|
||||
</para>
|
||||
|
@ -376,12 +376,15 @@ PostgreSQL documentation
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>-f</option> <literal>{ s | i | m | n | h }</literal></term>
|
||||
<term><option>-f</option> <literal>{ s | i | o | b | t | n | m | h }</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Forbids the use of particular scan and join methods:
|
||||
<literal>s</literal> and <literal>i</literal>
|
||||
disable sequential and index scans respectively, while
|
||||
disable sequential and index scans respectively,
|
||||
<literal>o</literal>, <literal>b</literal> and <literal>t</literal>
|
||||
disable index-only scans, bitmap index scans, and TID scans
|
||||
respectively, while
|
||||
<literal>n</literal>, <literal>m</literal>, and <literal>h</literal>
|
||||
disable nested-loop, merge and hash joins respectively.
|
||||
</para>
|
||||
|
Reference in New Issue
Block a user