1
1
<!--
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 $
3
3
PostgreSQL documentation
4
4
-->
5
5
@@ -20,7 +20,7 @@ PostgreSQL documentation
20
20
21
21
<refsynopsisdiv>
22
22
<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> ]
24
24
( { <replaceable class="parameter">column</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ <replaceable class="parameter">opclass</replaceable> ] [, ...] )
25
25
[ WITH ( <replaceable class="PARAMETER">storage_parameter</replaceable> = <replaceable class="PARAMETER">value</replaceable> [, ... ] ) ]
26
26
[ TABLESPACE <replaceable class="parameter">tablespace</replaceable> ]
@@ -110,6 +110,21 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
110
110
</listitem>
111
111
</varlistentry>
112
112
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
+
113
128
<varlistentry>
114
129
<term><replaceable class="parameter">name</replaceable></term>
115
130
<listitem>
@@ -239,6 +254,82 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
239
254
</variablelist>
240
255
241
256
</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>
242
333
</refsect1>
243
334
244
335
<refsect1>
@@ -339,15 +430,22 @@ Is this example correct?
339
430
To create a GiST index on a point attribute so that we
340
431
can efficiently use box operators on the result of the
341
432
conversion function:
342
- </para>
343
433
<programlisting>
344
434
CREATE INDEX pointloc
345
435
ON points USING GIST (point2box(location) box_ops);
346
436
SELECT * FROM points
347
437
WHERE point2box(points.pointloc) = boxes.box;
348
438
</programlisting>
439
+ </para>
349
440
-->
350
441
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
+
351
449
</refsect1>
352
450
353
451
<refsect1>
0 commit comments