|
- <?xml version="1.0" encoding="UTF-8" standalone="no"?>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE INDEX</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets V1.79.1" /><link rel="prev" href="sql-creategroup.html" title="CREATE GROUP" /><link rel="next" href="sql-createlanguage.html" title="CREATE LANGUAGE" /></head><body><div xmlns="http://www.w3.org/TR/xhtml1/transitional" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE INDEX</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-creategroup.html" title="CREATE GROUP">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 12.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createlanguage.html" title="CREATE LANGUAGE">Next</a></td></tr></table><hr></hr></div><div class="refentry" id="SQL-CREATEINDEX"><div class="titlepage"></div><a id="id-1.9.3.69.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE INDEX</span></h2><p>CREATE INDEX — define a new index</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
- CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] <em class="replaceable"><code>name</code></em> ] ON [ ONLY ] <em class="replaceable"><code>table_name</code></em> [ USING <em class="replaceable"><code>method</code></em> ]
- ( { <em class="replaceable"><code>column_name</code></em> | ( <em class="replaceable"><code>expression</code></em> ) } [ COLLATE <em class="replaceable"><code>collation</code></em> ] [ <em class="replaceable"><code>opclass</code></em> ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
- [ INCLUDE ( <em class="replaceable"><code>column_name</code></em> [, ...] ) ]
- [ WITH ( <em class="replaceable"><code>storage_parameter</code></em> [= <em class="replaceable"><code>value</code></em>] [, ... ] ) ]
- [ TABLESPACE <em class="replaceable"><code>tablespace_name</code></em> ]
- [ WHERE <em class="replaceable"><code>predicate</code></em> ]
- </pre></div><div class="refsect1" id="id-1.9.3.69.5"><h2>Description</h2><p>
- <code class="command">CREATE INDEX</code> constructs an index on the specified column(s)
- of the specified relation, which can be a table or a materialized view.
- Indexes are primarily used to enhance database performance (though
- inappropriate use can result in slower performance).
- </p><p>
- The key field(s) for the index are specified as column names,
- or alternatively as expressions written in parentheses.
- Multiple fields can be specified if the index method supports
- multicolumn indexes.
- </p><p>
- An index field can be an expression computed from the values of
- one or more columns of the table row. This feature can be used
- to obtain fast access to data based on some transformation of
- the basic data. For example, an index computed on
- <code class="literal">upper(col)</code> would allow the clause
- <code class="literal">WHERE upper(col) = 'JIM'</code> to use an index.
- </p><p>
- <span class="productname">PostgreSQL</span> provides the index methods
- B-tree, hash, GiST, SP-GiST, GIN, and BRIN. Users can also define their own
- index methods, but that is fairly complicated.
- </p><p>
- When the <code class="literal">WHERE</code> clause is present, a
- <em class="firstterm">partial index</em> is created.
- A partial index is an index that contains entries for only a portion of
- a table, usually a portion that is more useful for indexing than the
- rest of the table. For example, if you have a table that contains both
- billed and unbilled orders where the unbilled orders take up a small
- fraction of the total table and yet that is an often used section, you
- can improve performance by creating an index on just that portion.
- Another possible application is to use <code class="literal">WHERE</code> with
- <code class="literal">UNIQUE</code> to enforce uniqueness over a subset of a
- table. See <a class="xref" href="indexes-partial.html" title="11.8. Partial Indexes">Section 11.8</a> for more discussion.
- </p><p>
- The expression used in the <code class="literal">WHERE</code> clause can refer
- only to columns of the underlying table, but it can use all columns,
- not just the ones being indexed. Presently, subqueries and
- aggregate expressions are also forbidden in <code class="literal">WHERE</code>.
- The same restrictions apply to index fields that are expressions.
- </p><p>
- All functions and operators used in an index definition must be
- <span class="quote">“<span class="quote">immutable</span>”</span>, that is, their results must depend only on
- their arguments and never on any outside influence (such as
- the contents of another table or the current time). This restriction
- ensures that the behavior of the index is well-defined. To use a
- user-defined function in an index expression or <code class="literal">WHERE</code>
- clause, remember to mark the function immutable when you create it.
- </p></div><div class="refsect1" id="id-1.9.3.69.6"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">UNIQUE</code></span></dt><dd><p>
- Causes the system to check for
- duplicate values in the table when the index is created (if data
- already exist) and each time data is added. Attempts to
- insert or update data which would result in duplicate entries
- will generate an error.
- </p><p>
- Additional restrictions apply when unique indexes are applied to
- partitioned tables; see <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a>.
- </p></dd><dt><span class="term"><code class="literal">CONCURRENTLY</code></span></dt><dd><p>
- When this option is used, <span class="productname">PostgreSQL</span> will build the
- index without taking any locks that prevent concurrent inserts,
- updates, or deletes on the table; whereas a standard index build
- locks out writes (but not reads) on the table until it's done.
- There are several caveats to be aware of when using this option
- — see <a class="xref" href="sql-createindex.html#SQL-CREATEINDEX-CONCURRENTLY" title="Building Indexes Concurrently">Building Indexes Concurrently</a>.
- </p><p>
- For temporary tables, <code class="command">CREATE INDEX</code> is always
- non-concurrent, as no other session can access them, and
- non-concurrent index creation is cheaper.
- </p></dd><dt><span class="term"><code class="literal">IF NOT EXISTS</code></span></dt><dd><p>
- Do not throw an error if a relation with the same name already exists.
- A notice is issued in this case. Note that there is no guarantee that
- the existing index is anything like the one that would have been created.
- Index name is required when <code class="literal">IF NOT EXISTS</code> is specified.
- </p></dd><dt><span class="term"><code class="literal">INCLUDE</code></span></dt><dd><p>
- The optional <code class="literal">INCLUDE</code> clause specifies a
- list of columns which will be included in the index
- as <em class="firstterm">non-key</em> columns. A non-key column cannot
- be used in an index scan search qualification, and it is disregarded
- for purposes of any uniqueness or exclusion constraint enforced by
- the index. However, an index-only scan can return the contents of
- non-key columns without having to visit the index's table, since
- they are available directly from the index entry. Thus, addition of
- non-key columns allows index-only scans to be used for queries that
- otherwise could not use them.
- </p><p>
- It's wise to be conservative about adding non-key columns to an
- index, especially wide columns. If an index tuple exceeds the
- maximum size allowed for the index type, data insertion will fail.
- In any case, non-key columns duplicate data from the index's table
- and bloat the size of the index, thus potentially slowing searches.
- </p><p>
- Columns listed in the <code class="literal">INCLUDE</code> clause don't need
- appropriate operator classes; the clause can include
- columns whose data types don't have operator classes defined for
- a given access method.
- </p><p>
- Expressions are not supported as included columns since they cannot be
- used in index-only scans.
- </p><p>
- Currently, the B-tree and the GiST index access methods support this
- feature. In B-tree and the GiST indexes, the values of columns listed
- in the <code class="literal">INCLUDE</code> clause are included in leaf tuples
- which correspond to heap tuples, but are not included in upper-level
- index entries used for tree navigation.
- </p></dd><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
- The name of the index to be created. No schema name can be included
- here; the index is always created in the same schema as its parent
- table. If the name is omitted, <span class="productname">PostgreSQL</span> chooses a
- suitable name based on the parent table's name and the indexed column
- name(s).
- </p></dd><dt><span class="term"><code class="literal">ONLY</code></span></dt><dd><p>
- Indicates not to recurse creating indexes on partitions, if the
- table is partitioned. The default is to recurse.
- </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
- The name (possibly schema-qualified) of the table to be indexed.
- </p></dd><dt><span class="term"><em class="replaceable"><code>method</code></em></span></dt><dd><p>
- The name of the index method to be used. Choices are
- <code class="literal">btree</code>, <code class="literal">hash</code>,
- <code class="literal">gist</code>, <code class="literal">spgist</code>, <code class="literal">gin</code>, and
- <code class="literal">brin</code>.
- The default method is <code class="literal">btree</code>.
- </p></dd><dt><span class="term"><em class="replaceable"><code>column_name</code></em></span></dt><dd><p>
- The name of a column of the table.
- </p></dd><dt><span class="term"><em class="replaceable"><code>expression</code></em></span></dt><dd><p>
- An expression based on one or more columns of the table. The
- expression usually must be written with surrounding parentheses,
- as shown in the syntax. However, the parentheses can be omitted
- if the expression has the form of a function call.
- </p></dd><dt><span class="term"><em class="replaceable"><code>collation</code></em></span></dt><dd><p>
- The name of the collation to use for the index. By default,
- the index uses the collation declared for the column to be
- indexed or the result collation of the expression to be
- indexed. Indexes with non-default collations can be useful for
- queries that involve expressions using non-default collations.
- </p></dd><dt><span class="term"><em class="replaceable"><code>opclass</code></em></span></dt><dd><p>
- The name of an operator class. See below for details.
- </p></dd><dt><span class="term"><code class="literal">ASC</code></span></dt><dd><p>
- Specifies ascending sort order (which is the default).
- </p></dd><dt><span class="term"><code class="literal">DESC</code></span></dt><dd><p>
- Specifies descending sort order.
- </p></dd><dt><span class="term"><code class="literal">NULLS FIRST</code></span></dt><dd><p>
- Specifies that nulls sort before non-nulls. This is the default
- when <code class="literal">DESC</code> is specified.
- </p></dd><dt><span class="term"><code class="literal">NULLS LAST</code></span></dt><dd><p>
- Specifies that nulls sort after non-nulls. This is the default
- when <code class="literal">DESC</code> is not specified.
- </p></dd><dt><span class="term"><em class="replaceable"><code>storage_parameter</code></em></span></dt><dd><p>
- The name of an index-method-specific storage parameter. See
- <a class="xref" href="sql-createindex.html#SQL-CREATEINDEX-STORAGE-PARAMETERS" title="Index Storage Parameters">Index Storage Parameters</a>
- for details.
- </p></dd><dt><span class="term"><em class="replaceable"><code>tablespace_name</code></em></span></dt><dd><p>
- The tablespace in which to create the index. If not specified,
- <a class="xref" href="runtime-config-client.html#GUC-DEFAULT-TABLESPACE">default_tablespace</a> is consulted, or
- <a class="xref" href="runtime-config-client.html#GUC-TEMP-TABLESPACES">temp_tablespaces</a> for indexes on temporary
- tables.
- </p></dd><dt><span class="term"><em class="replaceable"><code>predicate</code></em></span></dt><dd><p>
- The constraint expression for a partial index.
- </p></dd></dl></div><div class="refsect2" id="SQL-CREATEINDEX-STORAGE-PARAMETERS"><h3>Index Storage Parameters</h3><p>
- The optional <code class="literal">WITH</code> clause specifies <em class="firstterm">storage
- parameters</em> for the index. Each index method has its own set of allowed
- storage parameters. The B-tree, hash, GiST and SP-GiST index methods all
- accept this parameter:
- </p><div class="variablelist"><dl class="variablelist"><dt id="INDEX-RELOPTION-FILLFACTOR"><span class="term"><code class="literal">fillfactor</code>
- <a id="id-1.9.3.69.6.3.3.1.1.2" class="indexterm"></a>
- </span></dt><dd><p>
- The fillfactor for an index is a percentage that determines how full
- the index method will try to pack index pages. For B-trees, leaf pages
- are filled to this percentage during initial index build, and also
- when extending the index at the right (adding new largest key values).
- If pages
- subsequently become completely full, they will be split, leading to
- gradual degradation in the index's efficiency. B-trees use a default
- fillfactor of 90, but any integer value from 10 to 100 can be selected.
- If the table is static then fillfactor 100 is best to minimize the
- index's physical size, but for heavily updated tables a smaller
- fillfactor is better to minimize the need for page splits. The
- other index methods use fillfactor in different but roughly analogous
- ways; the default fillfactor varies between methods.
- </p></dd></dl></div><p>
- B-tree indexes additionally accept this parameter:
- </p><div class="variablelist"><dl class="variablelist"><dt id="INDEX-RELOPTION-VACUUM-CLEANUP-INDEX-SCALE-FACTOR"><span class="term"><code class="literal">vacuum_cleanup_index_scale_factor</code>
- <a id="id-1.9.3.69.6.3.5.1.1.2" class="indexterm"></a>
- </span></dt><dd><p>
- Per-index value for <a class="xref" href="runtime-config-client.html#GUC-VACUUM-CLEANUP-INDEX-SCALE-FACTOR">vacuum_cleanup_index_scale_factor</a>.
- </p></dd></dl></div><p>
- GiST indexes additionally accept this parameter:
- </p><div class="variablelist"><dl class="variablelist"><dt id="INDEX-RELOPTION-BUFFERING"><span class="term"><code class="literal">buffering</code>
- <a id="id-1.9.3.69.6.3.7.1.1.2" class="indexterm"></a>
- </span></dt><dd><p>
- Determines whether the buffering build technique described in
- <a class="xref" href="gist-implementation.html#GIST-BUFFERING-BUILD" title="64.4.1. GiST Buffering Build">Section 64.4.1</a> is used to build the index. With
- <code class="literal">OFF</code> it is disabled, with <code class="literal">ON</code> it is enabled, and
- with <code class="literal">AUTO</code> it is initially disabled, but turned on
- on-the-fly once the index size reaches <a class="xref" href="runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE">effective_cache_size</a>. The default is <code class="literal">AUTO</code>.
- </p></dd></dl></div><p>
- GIN indexes accept different parameters:
- </p><div class="variablelist"><dl class="variablelist"><dt id="INDEX-RELOPTION-FASTUPDATE"><span class="term"><code class="literal">fastupdate</code>
- <a id="id-1.9.3.69.6.3.9.1.1.2" class="indexterm"></a>
- </span></dt><dd><p>
- This setting controls usage of the fast update technique described in
- <a class="xref" href="gin-implementation.html#GIN-FAST-UPDATE" title="66.4.1. GIN Fast Update Technique">Section 66.4.1</a>. It is a Boolean parameter:
- <code class="literal">ON</code> enables fast update, <code class="literal">OFF</code> disables it.
- (Alternative spellings of <code class="literal">ON</code> and <code class="literal">OFF</code> are
- allowed as described in <a class="xref" href="config-setting.html" title="19.1. Setting Parameters">Section 19.1</a>.) The
- default is <code class="literal">ON</code>.
- </p><div class="note"><h3 class="title">Note</h3><p>
- Turning <code class="literal">fastupdate</code> off via <code class="command">ALTER INDEX</code> prevents
- future insertions from going into the list of pending index entries,
- but does not in itself flush previous entries. You might want to
- <code class="command">VACUUM</code> the table or call <code class="function">gin_clean_pending_list</code>
- function afterward to ensure the pending list is emptied.
- </p></div></dd></dl></div><div class="variablelist"><dl class="variablelist"><dt id="INDEX-RELOPTION-GIN-PENDING-LIST-LIMIT"><span class="term"><code class="literal">gin_pending_list_limit</code>
- <a id="id-1.9.3.69.6.3.10.1.1.2" class="indexterm"></a>
- </span></dt><dd><p>
- Custom <a class="xref" href="runtime-config-client.html#GUC-GIN-PENDING-LIST-LIMIT">gin_pending_list_limit</a> parameter.
- This value is specified in kilobytes.
- </p></dd></dl></div><p>
- <acronym class="acronym">BRIN</acronym> indexes accept different parameters:
- </p><div class="variablelist"><dl class="variablelist"><dt id="INDEX-RELOPTION-PAGES-PER-RANGE"><span class="term"><code class="literal">pages_per_range</code>
- <a id="id-1.9.3.69.6.3.12.1.1.2" class="indexterm"></a>
- </span></dt><dd><p>
- Defines the number of table blocks that make up one block range for
- each entry of a <acronym class="acronym">BRIN</acronym> index (see <a class="xref" href="brin-intro.html" title="67.1. Introduction">Section 67.1</a>
- for more details). The default is <code class="literal">128</code>.
- </p></dd><dt id="INDEX-RELOPTION-AUTOSUMMARIZE"><span class="term"><code class="literal">autosummarize</code>
- <a id="id-1.9.3.69.6.3.12.2.1.2" class="indexterm"></a>
- </span></dt><dd><p>
- Defines whether a summarization run is invoked for the previous page
- range whenever an insertion is detected on the next one.
- </p></dd></dl></div></div><div class="refsect2" id="SQL-CREATEINDEX-CONCURRENTLY"><h3>Building Indexes Concurrently</h3><a id="id-1.9.3.69.6.4.2" class="indexterm"></a><p>
- Creating an index can interfere with regular operation of a database.
- Normally <span class="productname">PostgreSQL</span> locks the table to be indexed against
- writes and performs the entire index build with a single scan of the
- table. Other transactions can still read the table, but if they try to
- insert, update, or delete rows in the table they will block until the
- index build is finished. This could have a severe effect if the system is
- a live production database. Very large tables can take many hours to be
- indexed, and even for smaller tables, an index build can lock out writers
- for periods that are unacceptably long for a production system.
- </p><p>
- <span class="productname">PostgreSQL</span> supports building indexes without locking
- out writes. This method is invoked by specifying the
- <code class="literal">CONCURRENTLY</code> option of <code class="command">CREATE INDEX</code>.
- When this option is used,
- <span class="productname">PostgreSQL</span> must perform two scans of the table, and in
- addition it must wait for all existing transactions that could potentially
- modify or use the index to terminate. Thus
- this method requires more total work than a standard index build and takes
- significantly longer to complete. However, since it allows normal
- operations to continue while the index is built, this method is useful for
- adding new indexes in a production environment. Of course, the extra CPU
- and I/O load imposed by the index creation might slow other operations.
- </p><p>
- In a concurrent index build, the index is actually entered into
- the system catalogs in one transaction, then two table scans occur in
- two more transactions. Before each table scan, the index build must
- wait for existing transactions that have modified the table to terminate.
- After the second scan, the index build must wait for any transactions
- that have a snapshot (see <a class="xref" href="mvcc.html" title="Chapter 13. Concurrency Control">Chapter 13</a>) predating the second
- scan to terminate. Then finally the index can be marked ready for use,
- and the <code class="command">CREATE INDEX</code> command terminates.
- Even then, however, the index may not be immediately usable for queries:
- in the worst case, it cannot be used as long as transactions exist that
- predate the start of the index build.
- </p><p>
- If a problem arises while scanning the table, such as a deadlock or a
- uniqueness violation in a unique index, the <code class="command">CREATE INDEX</code>
- command will fail but leave behind an <span class="quote">“<span class="quote">invalid</span>”</span> index. This index
- will be ignored for querying purposes because it might be incomplete;
- however it will still consume update overhead. The <span class="application">psql</span>
- <code class="command">\d</code> command will report such an index as <code class="literal">INVALID</code>:
-
- </p><pre class="programlisting">
- postgres=# \d tab
- Table "public.tab"
- Column | Type | Collation | Nullable | Default
- --------+---------+-----------+----------+---------
- col | integer | | |
- Indexes:
- "idx" btree (col) INVALID
- </pre><p>
-
- The recommended recovery
- method in such cases is to drop the index and try again to perform
- <code class="command">CREATE INDEX CONCURRENTLY</code>. (Another possibility is
- to rebuild the index with <code class="command">REINDEX INDEX CONCURRENTLY</code>).
- </p><p>
- Another caveat when building a unique index concurrently is that the
- uniqueness constraint is already being enforced against other transactions
- when the second table scan begins. This means that constraint violations
- could be reported in other queries prior to the index becoming available
- for use, or even in cases where the index build eventually fails. Also,
- if a failure does occur in the second scan, the <span class="quote">“<span class="quote">invalid</span>”</span> index
- continues to enforce its uniqueness constraint afterwards.
- </p><p>
- Concurrent builds of expression indexes and partial indexes are supported.
- Errors occurring in the evaluation of these expressions could cause
- behavior similar to that described above for unique constraint violations.
- </p><p>
- Regular index builds permit other regular index builds on the
- same table to occur simultaneously, but only one concurrent index build
- can occur on a table at a time. In either case, schema modification of the
- table is not allowed while the index is being built. Another difference is
- that a regular <code class="command">CREATE INDEX</code> command can be performed
- within a transaction block, but <code class="command">CREATE INDEX CONCURRENTLY</code>
- cannot.
- </p><p>
- Concurrent builds for indexes on partitioned tables are currently not
- supported. However, you may concurrently build the index on each
- partition individually and then finally create the partitioned index
- non-concurrently in order to reduce the time where writes to the
- partitioned table will be locked out. In this case, building the
- partitioned index is a metadata only operation.
- </p></div></div><div class="refsect1" id="id-1.9.3.69.7"><h2>Notes</h2><p>
- See <a class="xref" href="indexes.html" title="Chapter 11. Indexes">Chapter 11</a> for information about when indexes can
- be used, when they are not used, and in which particular situations
- they can be useful.
- </p><p>
- Currently, only the B-tree, GiST, GIN, and BRIN index methods support
- multicolumn indexes. Up to 32 fields can be specified by default.
- (This limit can be altered when building
- <span class="productname">PostgreSQL</span>.) Only B-tree currently
- supports unique indexes.
- </p><p>
- An <em class="firstterm">operator class</em> can be specified for each
- column of an index. The operator class identifies the operators to be
- used by the index for that column. For example, a B-tree index on
- four-byte integers would use the <code class="literal">int4_ops</code> class;
- this operator class includes comparison functions for four-byte
- integers. In practice the default operator class for the column's data
- type is usually sufficient. The main point of having operator classes
- is that for some data types, there could be more than one meaningful
- ordering. For example, we might want to sort a complex-number data
- type either by absolute value or by real part. We could do this by
- defining two operator classes for the data type and then selecting
- the proper class when creating an index. More information about
- operator classes is in <a class="xref" href="indexes-opclass.html" title="11.10. Operator Classes and Operator Families">Section 11.10</a> and in <a class="xref" href="xindex.html" title="37.16. Interfacing Extensions to Indexes">Section 37.16</a>.
- </p><p>
- When <code class="literal">CREATE INDEX</code> is invoked on a partitioned
- table, the default behavior is to recurse to all partitions to ensure
- they all have matching indexes.
- Each partition is first checked to determine whether an equivalent
- index already exists, and if so, that index will become attached as a
- partition index to the index being created, which will become its
- parent index.
- If no matching index exists, a new index will be created and
- automatically attached; the name of the new index in each partition
- will be determined as if no index name had been specified in the
- command.
- If the <code class="literal">ONLY</code> option is specified, no recursion
- is done, and the index is marked invalid.
- (<code class="command">ALTER INDEX ... ATTACH PARTITION</code> marks the index
- valid, once all partitions acquire matching indexes.) Note, however,
- that any partition that is created in the future using
- <code class="command">CREATE TABLE ... PARTITION OF</code> will automatically
- have a matching index, regardless of whether <code class="literal">ONLY</code> is
- specified.
- </p><p>
- For index methods that support ordered scans (currently, only B-tree),
- the optional clauses <code class="literal">ASC</code>, <code class="literal">DESC</code>, <code class="literal">NULLS
- FIRST</code>, and/or <code class="literal">NULLS LAST</code> can be specified to modify
- the sort ordering of the index. Since an ordered index can be
- scanned either forward or backward, it is not normally useful to create a
- single-column <code class="literal">DESC</code> index — that sort ordering is already
- available with a regular index. The value of these options is that
- multicolumn indexes can be created that match the sort ordering requested
- by a mixed-ordering query, such as <code class="literal">SELECT ... ORDER BY x ASC, y
- DESC</code>. The <code class="literal">NULLS</code> options are useful if you need to support
- <span class="quote">“<span class="quote">nulls sort low</span>”</span> behavior, rather than the default <span class="quote">“<span class="quote">nulls
- sort high</span>”</span>, in queries that depend on indexes to avoid sorting steps.
- </p><p>
- For most index methods, the speed of creating an index is
- dependent on the setting of <a class="xref" href="runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM">maintenance_work_mem</a>.
- Larger values will reduce the time needed for index creation, so long
- as you don't make it larger than the amount of memory really available,
- which would drive the machine into swapping.
- </p><p>
- <span class="productname">PostgreSQL</span> can build indexes while
- leveraging multiple CPUs in order to process the table rows faster.
- This feature is known as <em class="firstterm">parallel index
- build</em>. For index methods that support building indexes
- in parallel (currently, only B-tree),
- <code class="varname">maintenance_work_mem</code> specifies the maximum
- amount of memory that can be used by each index build operation as
- a whole, regardless of how many worker processes were started.
- Generally, a cost model automatically determines how many worker
- processes should be requested, if any.
- </p><p>
- Parallel index builds may benefit from increasing
- <code class="varname">maintenance_work_mem</code> where an equivalent serial
- index build will see little or no benefit. Note that
- <code class="varname">maintenance_work_mem</code> may influence the number of
- worker processes requested, since parallel workers must have at
- least a <code class="literal">32MB</code> share of the total
- <code class="varname">maintenance_work_mem</code> budget. There must also be
- a remaining <code class="literal">32MB</code> share for the leader process.
- Increasing <a class="xref" href="runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-MAINTENANCE">max_parallel_maintenance_workers</a>
- may allow more workers to be used, which will reduce the time
- needed for index creation, so long as the index build is not
- already I/O bound. Of course, there should also be sufficient
- CPU capacity that would otherwise lie idle.
- </p><p>
- Setting a value for <code class="literal">parallel_workers</code> via <a class="xref" href="sql-altertable.html" title="ALTER TABLE"><span class="refentrytitle">ALTER TABLE</span></a> directly controls how many parallel
- worker processes will be requested by a <code class="command">CREATE
- INDEX</code> against the table. This bypasses the cost model
- completely, and prevents <code class="varname">maintenance_work_mem</code>
- from affecting how many parallel workers are requested. Setting
- <code class="literal">parallel_workers</code> to 0 via <code class="command">ALTER
- TABLE</code> will disable parallel index builds on the table in
- all cases.
- </p><div class="tip"><h3 class="title">Tip</h3><p>
- You might want to reset <code class="literal">parallel_workers</code> after
- setting it as part of tuning an index build. This avoids
- inadvertent changes to query plans, since
- <code class="literal">parallel_workers</code> affects
- <span class="emphasis"><em>all</em></span> parallel table scans.
- </p></div><p>
- While <code class="command">CREATE INDEX</code> with the
- <code class="literal">CONCURRENTLY</code> option supports parallel builds
- without special restrictions, only the first table scan is actually
- performed in parallel.
- </p><p>
- Use <a class="xref" href="sql-dropindex.html" title="DROP INDEX"><span class="refentrytitle">DROP INDEX</span></a>
- to remove an index.
- </p><p>
- Prior releases of <span class="productname">PostgreSQL</span> also had an
- R-tree index method. This method has been removed because
- it had no significant advantages over the GiST method.
- If <code class="literal">USING rtree</code> is specified, <code class="command">CREATE INDEX</code>
- will interpret it as <code class="literal">USING gist</code>, to simplify conversion
- of old databases to GiST.
- </p></div><div class="refsect1" id="id-1.9.3.69.8"><h2>Examples</h2><p>
- To create a unique B-tree index on the column <code class="literal">title</code> in
- the table <code class="literal">films</code>:
- </p><pre class="programlisting">
- CREATE UNIQUE INDEX title_idx ON films (title);
- </pre><p>
- </p><p>
- To create a unique B-tree index on the column <code class="literal">title</code>
- with included columns <code class="literal">director</code>
- and <code class="literal">rating</code> in the table <code class="literal">films</code>:
- </p><pre class="programlisting">
- CREATE UNIQUE INDEX title_idx ON films (title) INCLUDE (director, rating);
- </pre><p>
- </p><p>
- To create an index on the expression <code class="literal">lower(title)</code>,
- allowing efficient case-insensitive searches:
- </p><pre class="programlisting">
- CREATE INDEX ON films ((lower(title)));
- </pre><p>
- (In this example we have chosen to omit the index name, so the system
- will choose a name, typically <code class="literal">films_lower_idx</code>.)
- </p><p>
- To create an index with non-default collation:
- </p><pre class="programlisting">
- CREATE INDEX title_idx_german ON films (title COLLATE "de_DE");
- </pre><p>
- </p><p>
- To create an index with non-default sort ordering of nulls:
- </p><pre class="programlisting">
- CREATE INDEX title_idx_nulls_low ON films (title NULLS FIRST);
- </pre><p>
- </p><p>
- To create an index with non-default fill factor:
- </p><pre class="programlisting">
- CREATE UNIQUE INDEX title_idx ON films (title) WITH (fillfactor = 70);
- </pre><p>
- </p><p>
- To create a <acronym class="acronym">GIN</acronym> index with fast updates disabled:
- </p><pre class="programlisting">
- CREATE INDEX gin_idx ON documents_table USING GIN (locations) WITH (fastupdate = off);
- </pre><p>
- </p><p>
- To create an index on the column <code class="literal">code</code> in the table
- <code class="literal">films</code> and have the index reside in the tablespace
- <code class="literal">indexspace</code>:
- </p><pre class="programlisting">
- CREATE INDEX code_idx ON films (code) TABLESPACE indexspace;
- </pre><p>
- </p><p>
- To create a GiST index on a point attribute so that we
- can efficiently use box operators on the result of the
- conversion function:
- </p><pre class="programlisting">
- CREATE INDEX pointloc
- ON points USING gist (box(location,location));
- SELECT * FROM points
- WHERE box(location,location) && '(0,0),(1,1)'::box;
- </pre><p>
- </p><p>
- To create an index without locking out writes to the table:
- </p><pre class="programlisting">
- CREATE INDEX CONCURRENTLY sales_quantity_index ON sales_table (quantity);
- </pre></div><div class="refsect1" id="id-1.9.3.69.9"><h2>Compatibility</h2><p>
- <code class="command">CREATE INDEX</code> is a
- <span class="productname">PostgreSQL</span> language extension. There
- are no provisions for indexes in the SQL standard.
- </p></div><div class="refsect1" id="id-1.9.3.69.10"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-alterindex.html" title="ALTER INDEX"><span class="refentrytitle">ALTER INDEX</span></a>, <a class="xref" href="sql-dropindex.html" title="DROP INDEX"><span class="refentrytitle">DROP INDEX</span></a>, <a class="xref" href="sql-reindex.html" title="REINDEX"><span class="refentrytitle">REINDEX</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-creategroup.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createlanguage.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE GROUP </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> CREATE LANGUAGE</td></tr></table></div></body></html>
|