Skip to main content
Creates a secondary index on an existing table. The index kind is selected by the USING clause. This page is the syntax reference. For how each index works, when to use it, and how to tune it, follow the link next to each form into Storage and indexing.
Aggregating indexes use a different grammar; see CREATE AGGREGATING INDEX. To remove an index, see DROP INDEX.

Syntax

Index names are unique per database. You can create multiple indexes on one table, but at most one index per indexed expression.

SKIP_INDEX: data skipping (minmax)

Skips granules whose stored min/max range cannot match a comparison predicate. For mechanism and tuning, see Data skipping index.

INVERTED_INDEX: exact value membership

Maps each value to the rows that contain it. Once the index exists, =, IN, and bounded range predicates over the column are matched automatically, with has_all_tokens available for ARRAY(TEXT) membership. For mechanism and tuning, see Inverted index.
Indexes overlapping n-grams to accelerate search, which is equivalent to LIKE '%pattern%'. For mechanism and tuning, see Full-text search index.
Builds an HNSW graph for approximate nearest-neighbor search, queried with the vector_search() TVF. The HNSW form has its own parameter set, documented on CREATE VECTOR SEARCH INDEX. For mechanism and tuning, see Vector search index.

Index creation on populated tables

When you create an index on a table that already contains data, existing tablets carry no index data until they are rewritten. Run VACUUM with REINDEX=TRUE to backfill them. All subsequent inserts populate the index automatically.

See also