mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
CREATE INDEX ... INCLUDING (column[, ...])
Now indexes (but only B-tree for now) can contain "extra" column(s) which doesn't participate in index structure, they are just stored in leaf tuples. It allows to use index only scan by using single index instead of two or more indexes. Author: Anastasia Lubennikova with minor editorializing by me Reviewers: David Rowley, Peter Geoghegan, Jeff Janes
This commit is contained in:
@ -3557,6 +3557,14 @@
|
||||
<literal>pg_class.relnatts</literal>)</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>indnkeyatts</structfield></entry>
|
||||
<entry><type>int2</type></entry>
|
||||
<entry></entry>
|
||||
<entry>The number of key columns in the index. "Key columns" are ordinary
|
||||
index columns in contrast with "included" columns.</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry><structfield>indisunique</structfield></entry>
|
||||
<entry><type>bool</type></entry>
|
||||
|
@ -117,6 +117,8 @@ typedef struct IndexAmRoutine
|
||||
bool amclusterable;
|
||||
/* does AM handle predicate locks? */
|
||||
bool ampredlocks;
|
||||
/* does AM support columns included with clause INCLUDING? */
|
||||
bool amcaninclude;
|
||||
/* type of data stored in index, or InvalidOid if variable */
|
||||
Oid amkeytype;
|
||||
|
||||
@ -858,7 +860,8 @@ amrestrpos (IndexScanDesc scan);
|
||||
using <firstterm>unique indexes</>, which are indexes that disallow
|
||||
multiple entries with identical keys. An access method that supports this
|
||||
feature sets <structfield>amcanunique</> true.
|
||||
(At present, only b-tree supports it.)
|
||||
(At present, only B-tree supports it.) Columns which are present in the
|
||||
<literal>INCLUDING</> clause are not used to enforce uniqueness.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -643,7 +643,8 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);
|
||||
Indexes can also be used to enforce uniqueness of a column's value,
|
||||
or the uniqueness of the combined values of more than one column.
|
||||
<synopsis>
|
||||
CREATE UNIQUE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> (<replaceable>column</replaceable> <optional>, ...</optional>);
|
||||
CREATE UNIQUE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> (<replaceable>column</replaceable> <optional>, ...</optional>)
|
||||
<optional>INCLUDING (<replaceable>column</replaceable> <optional>, ...</optional>)</optional>;
|
||||
</synopsis>
|
||||
Currently, only B-tree indexes can be declared unique.
|
||||
</para>
|
||||
@ -652,7 +653,9 @@ CREATE UNIQUE INDEX <replaceable>name</replaceable> ON <replaceable>table</repla
|
||||
When an index is declared unique, multiple table rows with equal
|
||||
indexed values are not allowed. Null values are not considered
|
||||
equal. A multicolumn unique index will only reject cases where all
|
||||
indexed columns are equal in multiple rows.
|
||||
indexed columns are equal in multiple rows. Columns included with clause
|
||||
<literal>INCLUDING</literal> aren't used to enforce constraints (UNIQUE,
|
||||
PRIMARY KEY, etc).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -23,6 +23,7 @@ PostgreSQL documentation
|
||||
<synopsis>
|
||||
CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <replaceable class="parameter">name</replaceable> ] ON <replaceable class="parameter">table_name</replaceable> [ USING <replaceable class="parameter">method</replaceable> ]
|
||||
( { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">opclass</replaceable> ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
|
||||
[ INCLUDING ( <replaceable class="parameter">column_name</replaceable> [, ...] ) ]
|
||||
[ WITH ( <replaceable class="PARAMETER">storage_parameter</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] ) ]
|
||||
[ TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
|
||||
[ WHERE <replaceable class="parameter">predicate</replaceable> ]
|
||||
@ -138,6 +139,35 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <replaceable class=
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>INCLUDING</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
An optional <literal>INCLUDING</> clause allows a list of columns to be
|
||||
specified which will be included in the index, in the non-key portion of
|
||||
the index. Columns which are part of this clause cannot also exist in
|
||||
the key columns portion of the index, and vice versa. The
|
||||
<literal>INCLUDING</> columns exist solely to allow more queries to
|
||||
benefit from <firstterm>index-only scans</> by including certain
|
||||
columns in the index, the value of which would otherwise have to be
|
||||
obtained by reading
|
||||
the table's heap. Having these columns in the <literal>INCLUDING</>
|
||||
clause in some cases allows <productname>PostgreSQL</> to skip the heap
|
||||
read completely. This also allows <literal>UNIQUE</> indexes to be
|
||||
defined on one set of columns, which can include another set of column
|
||||
in the <literal>INCLUDING</> clause, on which the uniqueness is not
|
||||
enforced upon. It's the same with other constraints (PRIMARY KEY and
|
||||
EXCLUDE). This can also can be used for non-unique indexes as any
|
||||
columns which are not required for the searching or ordering of records
|
||||
can be included in the <literal>INCLUDING</> clause, which can slightly
|
||||
reduce the size of the index, due to storing included attributes only
|
||||
in leaf index pages. Currently, only the B-tree access method supports
|
||||
this feature. Expressions as included columns are not supported since
|
||||
they cannot be used in index-only scan.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable class="parameter">name</replaceable></term>
|
||||
<listitem>
|
||||
@ -599,13 +629,22 @@ Indexes:
|
||||
<title>Examples</title>
|
||||
|
||||
<para>
|
||||
To create a B-tree index on the column <literal>title</literal> in
|
||||
To create a unique B-tree index on the column <literal>title</literal> in
|
||||
the table <literal>films</literal>:
|
||||
<programlisting>
|
||||
CREATE UNIQUE INDEX title_idx ON films (title);
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To create a unique B-tree index on the column <literal>title</literal>
|
||||
and included columns <literal>director</literal> and <literal>rating</literal>
|
||||
in the table <literal>films</literal>:
|
||||
<programlisting>
|
||||
CREATE UNIQUE INDEX title_idx ON films (title) INCLUDING (director, rating);
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To create an index on the expression <literal>lower(title)</>,
|
||||
allowing efficient case-insensitive searches:
|
||||
|
@ -59,8 +59,8 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
|
||||
|
||||
[ CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ]
|
||||
{ CHECK ( <replaceable class="PARAMETER">expression</replaceable> ) [ NO INHERIT ] |
|
||||
UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) <replaceable class="PARAMETER">index_parameters</replaceable> |
|
||||
PRIMARY KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) <replaceable class="PARAMETER">index_parameters</replaceable> |
|
||||
UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) <replaceable class="PARAMETER">index_parameters</replaceable> <optional>INCLUDING (<replaceable class="PARAMETER">column_name</replaceable> [, ...])</optional> |
|
||||
PRIMARY KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) <replaceable class="PARAMETER">index_parameters</replaceable> <optional>INCLUDING (<replaceable class="PARAMETER">column_name</replaceable> [, ...])</optional> |
|
||||
EXCLUDE [ USING <replaceable class="parameter">index_method</replaceable> ] ( <replaceable class="parameter">exclude_element</replaceable> WITH <replaceable class="parameter">operator</replaceable> [, ... ] ) <replaceable class="parameter">index_parameters</replaceable> [ WHERE ( <replaceable class="parameter">predicate</replaceable> ) ] |
|
||||
FOREIGN KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] ) REFERENCES <replaceable class="PARAMETER">reftable</replaceable> [ ( <replaceable class="PARAMETER">refcolumn</replaceable> [, ... ] ) ]
|
||||
[ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE <replaceable class="parameter">action</replaceable> ] [ ON UPDATE <replaceable class="parameter">action</replaceable> ] }
|
||||
@ -476,8 +476,8 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>UNIQUE</> (column constraint)</term>
|
||||
<term><literal>UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] )</> (table constraint)</term>
|
||||
|
||||
<term><literal>UNIQUE ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] )
|
||||
<optional>INCLUDING ( <replaceable class="PARAMETER">column_name</replaceable> [, ...])</optional></> (table constraint)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>UNIQUE</literal> constraint specifies that a
|
||||
@ -498,12 +498,26 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
|
||||
primary key constraint defined for the table. (Otherwise it
|
||||
would just be the same constraint listed twice.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Adding a unique constraint will automatically create a unique btree
|
||||
index on the column or group of columns used in the constraint.
|
||||
Optional clause <literal>INCLUDING</literal> allows to add into the index
|
||||
a portion of columns on which the uniqueness is not enforced upon.
|
||||
Note, that althogh constraint is not enforced upon included columns, it still
|
||||
depends on them. Consequently, some operations on these columns (e.g. <literal>DROP COLUMN</literal>)
|
||||
can cause cascade constraint and index deletion.
|
||||
See paragraph about <literal>INCLUDING</literal> in
|
||||
<xref linkend="SQL-CREATEINDEX"> for more information.
|
||||
</para>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>PRIMARY KEY</> (column constraint)</term>
|
||||
<term><literal>PRIMARY KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] )</> (table constraint)</term>
|
||||
<term><literal>PRIMARY KEY ( <replaceable class="PARAMETER">column_name</replaceable> [, ... ] )
|
||||
<optional>INCLUDING ( <replaceable class="PARAMETER">column_name</replaceable> [, ...])</optional></> (table constraint)</term>
|
||||
<listitem>
|
||||
<para>
|
||||
The <literal>PRIMARY KEY</> constraint specifies that a column or
|
||||
@ -526,6 +540,18 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
|
||||
about the design of the schema, since a primary key implies that other
|
||||
tables can rely on this set of columns as a unique identifier for rows.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Adding a <literal>PRIMARY KEY</literal> constraint will automatically create a unique btree
|
||||
index on the column or group of columns used in the constraint.
|
||||
Optional clause <literal>INCLUDING</literal> allows to add into the index
|
||||
a portion of columns on which the constraint is not enforced upon.
|
||||
Note, that althogh constraint is not enforced upon included columns, it still
|
||||
depends on them. Consequently, some operations on these columns (e.g. <literal>DROP COLUMN</literal>)
|
||||
can cause cascade constraint and index deletion.
|
||||
See paragraph about <literal>INCLUDING</literal> in
|
||||
<xref linkend="SQL-CREATEINDEX"> for more information.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
Reference in New Issue
Block a user