diff options
author | Teodor Sigaev <teodor@sigaev.ru> | 2016-04-08 19:31:49 +0300 |
---|---|---|
committer | Teodor Sigaev <teodor@sigaev.ru> | 2016-04-08 19:45:59 +0300 |
commit | 386e3d7609c49505e079c40c65919d99feb82505 (patch) | |
tree | dd8f434e5401588c2b4f9e2068f396c5ce198cf6 /doc/src | |
parent | 339025c68f95d3cb2c42478109cafeaf414c7fe0 (diff) |
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
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/sgml/catalogs.sgml | 8 | ||||
-rw-r--r-- | doc/src/sgml/indexam.sgml | 5 | ||||
-rw-r--r-- | doc/src/sgml/indices.sgml | 7 | ||||
-rw-r--r-- | doc/src/sgml/ref/create_index.sgml | 41 | ||||
-rw-r--r-- | doc/src/sgml/ref/create_table.sgml | 36 |
5 files changed, 88 insertions, 9 deletions
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index d6b60db0744..342d5ecb037 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -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> diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml index b36889b856b..340904142e4 100644 --- a/doc/src/sgml/indexam.sgml +++ b/doc/src/sgml/indexam.sgml @@ -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> diff --git a/doc/src/sgml/indices.sgml b/doc/src/sgml/indices.sgml index 5f72e7d0735..7c4fdc0403f 100644 --- a/doc/src/sgml/indices.sgml +++ b/doc/src/sgml/indices.sgml @@ -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> diff --git a/doc/src/sgml/ref/create_index.sgml b/doc/src/sgml/ref/create_index.sgml index 7dee4055dbc..25b3c26f551 100644 --- a/doc/src/sgml/ref/create_index.sgml +++ b/doc/src/sgml/ref/create_index.sgml @@ -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> ] @@ -139,6 +140,35 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <replaceable class= </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> <para> @@ -599,7 +629,7 @@ 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); @@ -607,6 +637,15 @@ CREATE UNIQUE INDEX title_idx ON films (title); </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: <programlisting> diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index d1807ed0dbf..473023e88e4 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -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> |