11<!--
2- $PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.55 2006/07/11 21:05:57 tgl Exp $
2+ $PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.56 2006/08/25 04:06:45 tgl Exp $
33PostgreSQL documentation
44-->
55
@@ -20,7 +20,7 @@ PostgreSQL documentation
2020
2121 <refsynopsisdiv>
2222<synopsis>
23- CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table</replaceable> [ USING <replaceable class="parameter">method</replaceable> ]
23+ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table</replaceable> [ USING <replaceable class="parameter">method</replaceable> ]
2424 ( { <replaceable class="parameter">column</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ <replaceable class="parameter">opclass</replaceable> ] [, ...] )
2525 [ WITH ( <replaceable class="PARAMETER">storage_parameter</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] ) ]
2626 [ TABLESPACE <replaceable class="parameter">tablespace</replaceable> ]
@@ -110,6 +110,21 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
110110 </listitem>
111111 </varlistentry>
112112
113+ <varlistentry>
114+ <term><literal>CONCURRENTLY</literal></term>
115+ <listitem>
116+ <para>
117+ When this option is used, <productname>PostgreSQL</> will build the
118+ index without taking any locks that prevent concurrent inserts,
119+ updates, or deletes on the table; whereas a standard index build
120+ locks out writes (but not reads) on the table until it's done.
121+ There are several caveats to be aware of when using this option
122+ — see <xref linkend="SQL-CREATEINDEX-CONCURRENTLY"
123+ endterm="SQL-CREATEINDEX-CONCURRENTLY-title">.
124+ </para>
125+ </listitem>
126+ </varlistentry>
127+
113128 <varlistentry>
114129 <term><replaceable class="parameter">name</replaceable></term>
115130 <listitem>
@@ -239,6 +254,82 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
239254 </variablelist>
240255
241256 </refsect2>
257+
258+ <refsect2 id="SQL-CREATEINDEX-CONCURRENTLY">
259+ <title id="SQL-CREATEINDEX-CONCURRENTLY-title">Building Indexes Concurrently</title>
260+
261+ <indexterm zone="SQL-CREATEINDEX-CONCURRENTLY">
262+ <primary>index</primary>
263+ <secondary>building concurrently</secondary>
264+ </indexterm>
265+
266+ <para>
267+ Creating an index for a large table can be a long operation. In large data
268+ warehousing applications it can easily take hours or even days to build
269+ indexes. It's important to understand the impact creating indexes has on a
270+ system.
271+ </para>
272+
273+ <para>
274+ Normally <productname>PostgreSQL</> locks the table to be indexed against
275+ writes and performs the entire index build with a single scan of the
276+ table. Other transactions can still read the table, but if they try to
277+ insert, update, or delete rows in the table they will block until the
278+ index build is finished.
279+ </para>
280+
281+ <para>
282+ <productname>PostgreSQL</> also supports building indexes without locking
283+ out writes. This method is invoked by specifying the
284+ <literal>CONCURRENTLY</> option of <command>CREATE INDEX</>.
285+ When this option is used,
286+ <productname>PostgreSQL</> must perform two scans of the table, and in
287+ addition it must wait for all existing transactions to terminate. Thus
288+ this method requires more total work than a standard index build and takes
289+ significantly longer to complete. However, since it allows normal
290+ operations to continue while the index is built, this method is useful for
291+ adding new indexes in a production environment. Of course, the extra CPU
292+ and I/O load imposed by the index creation may slow other operations.
293+ </para>
294+
295+ <para>
296+ If a problem arises during the second scan of the table, such as a
297+ uniqueness violation in a unique index, the <command>CREATE INDEX</>
298+ command will fail but leave behind an <quote>invalid</> index. This index
299+ will be ignored for querying purposes because it may be incomplete;
300+ however it will still consume update overhead. The recommended recovery
301+ method in such cases is to drop the index and try again to perform
302+ <command>CREATE INDEX CONCURRENTLY</>. (Another possibility is to rebuild
303+ the index with <command>REINDEX</>. However, since <command>REINDEX</>
304+ does not support concurrent builds, this option is unlikely to seem
305+ attractive.)
306+ </para>
307+
308+ <para>
309+ Another caveat when building a unique index concurrently is that the
310+ uniqueness constraint is already being enforced against other transactions
311+ when the second table scan begins. This means that constraint violations
312+ could be reported in other queries prior to the index becoming available
313+ for use, or even in cases where the index build eventually fails. Also,
314+ if a failure does occur in the second scan, the <quote>invalid</> index
315+ continues to enforce its uniqueness constraint afterwards.
316+ </para>
317+
318+ <para>
319+ Concurrent builds of expression indexes and partial indexes are supported.
320+ Errors occurring in the evaluation of these expressions could cause
321+ behavior similar to that described above for unique constraint violations.
322+ </para>
323+
324+ <para>
325+ Regular index builds permit other regular index builds on the
326+ same table to occur in parallel, but only one concurrent index build
327+ can occur on a table at a time. In both cases, no other types of schema
328+ modification on the table are allowed meanwhile. Another difference
329+ is that a regular <command>CREATE INDEX</> command can be performed within
330+ a transaction block, but <command>CREATE INDEX CONCURRENTLY</> cannot.
331+ </para>
332+ </refsect2>
242333 </refsect1>
243334
244335 <refsect1>
@@ -339,15 +430,22 @@ Is this example correct?
339430 To create a GiST index on a point attribute so that we
340431 can efficiently use box operators on the result of the
341432 conversion function:
342- </para>
343433 <programlisting>
344434CREATE INDEX pointloc
345435 ON points USING GIST (point2box(location) box_ops);
346436SELECT * FROM points
347437 WHERE point2box(points.pointloc) = boxes.box;
348438 </programlisting>
439+ </para>
349440-->
350441
442+ <para>
443+ To create an index without locking out writes to the table:
444+ <programlisting>
445+ CREATE INDEX CONCURRENTLY sales_quantity_index ON sales_table (quantity);
446+ </programlisting>
447+ </para>
448+
351449 </refsect1>
352450
353451 <refsect1>
0 commit comments