Optimize query access paths
Speed up lookups or sorting on frequently queried columns.
Drizzle ORM · Function
Drizzle’s index function declares a database index on one or more table columns or expressions. Configure it with methods such as .on(), .using(), .where(), and .concurrently() where supported.
The index function creates a table-index declaration that Drizzle can use when generating database schema changes. Give it a name when needed, then configure indexed columns with .on(); the declaration is returned from the table callback alongside other indexes or constraints.
index(name).on(...columns)
index(name).onOnly(...columns)
index(name).using(method, ...columns)| Name | Type | Description |
|---|---|---|
name | string | The index name; optional for simple column indexes but recommended for expression-based indexes. |
columns / expressions | columns or SQL expressions | One or more table columns or SQL expressions passed to .on(), .onOnly(), or .using(). |
An index declaration used in the table callback and by Drizzle schema and migration tooling.
index for ordinary indexes and uniqueIndex when indexed values must be unique..on()..using() selects an index method and accepts ordered columns or SQL expressions as indexed items..where() using a SQL expression.push, changes to index expressions, predicates, or operator classes may not produce migration statements; use the documented remove-and-readd workflow.import { index, pgTable, serial, text } from "drizzle-orm/pg-core";
export const users = pgTable("users", {
id: serial().primaryKey(),
name: text().notNull(),
}, (table) => [
index("users_name_idx").on(table.name),
]);Defines a PostgreSQL table and adds a named B-tree index on the name column.
Speed up lookups or sorting on frequently queried columns.
Create a multicolumn index for queries filtering or ordering by a column combination.
Index a computed SQL expression, such as a lowercased text value.
Create a PostgreSQL partial or concurrently built index.
Use index(name).on(columns...) inside the table callback. The declaration describes an ordinary database index, while uniqueIndex(name).on(...) declares a unique one.
Follow-up: How would you index an SQL expression? Use .on(sql...) and provide the index name explicitly, because expression-based indexes should not depend on generated names.
The index API supports configuration beyond columns, including .using(), .where(), and .concurrently() for PostgreSQL declarations. .onOnly() is available when the PostgreSQL index should be created with ON ONLY.
Follow-up: How can an index use a PostgreSQL operator class? Pass the column expression through .op('operator_class'), together with the relevant index method if required.
For a normal column index, Drizzle can generate an index name when one is omitted. The documentation specifically recommends supplying a name whenever at least one indexed item is an expression.
Follow-up: What happens with an existing index changed through push? Changes to expressions, where clauses, and operator classes may require temporarily removing the index, pushing, then adding the changed declaration and pushing again.
uniqueIndexpgTablesql.on().onOnly().using().where().concurrently()