CREATE INDEX creates an index for a table. improve your database’s performance by helping SQL locate data without having to look through every row of a table.
Indexes are automatically created for a table’s and columns. When querying a table, CockroachDB uses the fastest index. For more information about that process, see Index Selection in CockroachDB.
The following types cannot be included in an index key, but can be stored (and used in a covered query) using the clause:
- The computed type, even if it is constructed from indexed fields
CREATE INDEX statement performs a schema change. For more information about how online schema changes work in
CockroachDB, see .
Required privileges
The user must have theCREATE on the table.
Synopsis
Standard index
GIN index
Parameters
| Parameter | Description |
|---|---|
UNIQUE | Apply the to the indexed columns. This causes the system to check for existing duplicate values on index creation. It also applies the UNIQUE constraint at the table level, so the system checks for duplicate values when inserting or updating data. |
INVERTED | Create a on the schemaless data in the specified column. You can also use the PostgreSQL-compatible syntax USING GIN. For more details, see . |
VECTOR | Create a on the specifed column. For more details, refer to . |
IF NOT EXISTS | Create a new index only if an index of the same name does not already exist; if one does exist, do not return an error. |
opt\_index\_name index\_name | The name of the index to create, which must be unique to its table and follow these . If you do not specify a name, CockroachDB uses the format \_\_key/idx. key indicates the index applies the UNIQUE constraint; idx indicates it does not. Example: accounts\_balance\_idx |
table\_name | The name of the table you want to create the index on. |
USING name | An optional clause for compatibility with third-party tools. Accepted values for name are btree, gin, and gist, with btree for a standard secondary index, gin as the PostgreSQL-compatible syntax for a GIN index, gist for a , and cspann for a . hnsw is aliased to cspann for compatibility with [pgvector](https://github. com/pgvector/pgvector) syntax. |
name | The name of the column you want to index. For , you can use the crdb\_region column within the index in the event the original index may contain non-unique entries across multiple, unique regions. |
ASC or DESC | Sort the column in ascending (ASC) or descending (DESC) order in the index. How columns are sorted affects query results, particularly when using LIMIT. Default: ASC |
STORING... | Store (but do not sort) each column whose name you include. For information on when to use STORING, see Store Columns. Note that columns that are part of a table’s cannot be specified as STORING columns in secondary indexes on the table. COVERING and INCLUDE are aliases for STORING and work identically. |
opt\_partition\_by | An option that lets you . As of CockroachDB v21.1 and later, most users should use . Indexes against regional by row tables are automatically partitioned, so explicit index partitioning is not required. |
opt\_where\_clause | An optional WHERE clause that defines the predicate boolean expression of a . |
opt\_index\_visible | An optional VISIBLE, NOT VISIBLE, or VISIBILITY clause that indicates that an . If not visible, the index will not be used in queries unless it is specifically selected with an or the property is overridden with the . For examples, see . Indexes that are not visible are still used to enforce UNIQUE and FOREIGN KEY . For more considerations, see . |
USING HASH | Creates a . |
WITH storage\_parameter | A comma-separated list of . Supported parameters include fillfactor, s2\_max\_level, s2\_level\_mod, s2\_max\_cells, geometry\_min\_x, geometry\_max\_x, geometry\_min\_y, and geometry\_max\_y. The fillfactor parameter is a no-op, allowed for PostgreSQL-compatibility. For details, see . For an example, see . |
CONCURRENTLY | Optional, no-op syntax for PostgreSQL compatibility. All indexes are created concurrently in CockroachDB. |
Viewing schema changes
This schema change statement is registered as a job. You can view long-running jobs with .Examples
Setup
To follow along, run to start a temporary, in-memory cluster with the sample dataset preloaded:Create standard indexes
To create the most efficient indexes, we recommend reviewing:Single-column indexes
Single-column indexes sort the values of a single column.Multiple-column indexes
Multiple-column indexes sort columns in the order you list them.Unique indexes
Unique indexes do not allow duplicate values among their columns.Create GIN indexes
You can create on schemaless data in a column.Create trigram indexes
You can create onSTRING columns by specifying the gin_trgm_ops or gist_trgm_ops opclass:
GIN and GiST indexes are implemented identically on CockroachDB.
GIN and GIST are therefore synonymous when
defining a trigram index.Create spatial indexes
You can create onGEOMETRY and GEOGRAPHY columns. Spatial indexes are a special type of .
To create a spatial index on a GEOMETRY column:
CREATE INVERTED INDEX... syntax. Only the syntax shown here is supported.
For advanced users, there are a number of that can be passed in using the syntax WITH (var1=val1, var2=val2) as follows:
Most users should not change the default spatial index settings. There is a risk that you will get worse performance
by changing the default settings. For more information, see .
Create vector indexes
You can create on columns. To create a vector index on aVECTOR column named embedding:
Store columns
Storing a column improves the performance of queries that retrieve (but do not filter) its values.name values from the above index only when a query’s WHERE clause filters city.
An index that stores all the columns needed by a query is also known as a covering index for that query. When a
query has a covering index, CockroachDB can use that index directly instead of doing an “index join” with the primary
index, which is likely to be slower.
Change column sort order
To sort columns in descending order, you must explicitly set the option when creating the index. (Ascending order is the default.)ORDER BY clause.
Query specific indexes
Normally, CockroachDB selects the index that it calculates will scan the fewest rows. However, you can override that selection and specify the name of the index you want to use. To find the name, use .@primary alias to use the table’s primary key in your query if no secondary index explicitly named primary exists on that table.
Create a hash-sharded secondary index
We . If a table must be indexed on sequential keys, use . Hash-sharded indexes distribute sequential traffic uniformly across ranges, eliminating single-range and improving write performance on sequentially-keyed indexes at a small cost to read performance. Let’s assume theevents table already exists:

