Se puede definir un índice en más de una columna de una tabla. Por ejemplo, si tienes una tabla de esta forma:
CREATE TABLE test2 ( major int, minor int, name varchar );
(digamos, mantienes tu directorio /dev
en una base de datos...) y con frecuencia realizas consultas como:
SELECT name FROM test2 WHERE major =constanteAND minor =constante;
entonces podría ser apropiado definir un índice en las columnas
major y
minor juntas, por ejemplo:
CREATE INDEX test2_mm_idx ON test2 (major, minor);
Actualmente, solo los tipos de índice B-tree, GiST, GIN y BRIN admiten
índices de múltiples columnas clave. La posibilidad de tener múltiples columnas
clave es independiente de si se pueden añadir columnas INCLUDE
al índice. Los índices pueden tener hasta 32 columnas,
incluidas las columnas INCLUDE. (Este límite se puede
alterar al compilar PostgreSQL; consulta el
archivo pg_config_manual.h).
Un índice B-tree multicolumna se puede usar con condiciones de consulta que involucren cualquier subconjunto de las columnas del índice, pero el índice es más eficiente cuando hay restricciones en las columnas iniciales (las situadas más a la izquierda). La regla exacta es que las restricciones de igualdad en las columnas iniciales, más cualquier restricción de desigualdad en la primera columna que no tenga una restricción de igualdad, se usarán siempre para limitar la parte del índice que se escanea. Las restricciones en las columnas a la derecha de estas columnas se comprueban en el índice, por lo que siempre ahorrarán visitas a la tabla propiamente dicha, pero no reducen necesariamente la parte del índice que tiene que escanearse. Si un escaneo de índice B-tree puede aplicar la optimización de escaneo por salto (skip scan) de manera efectiva, aplicará cada restricción de columna al navegar a través del índice mediante búsquedas repetidas en el índice. Esto puede reducir la parte del índice que tiene que leerse, a pesar de que una o más columnas (anteriores a la columna de índice menos significativa del predicado de la consulta) carezcan de una restricción de igualdad convencional. El escaneo por salto funciona generando una restricción de igualdad dinámica internamente, que coincide con cada valor posible en una columna de índice (aunque solo se da en una columna que carece de una restricción de igualdad proveniente del predicado de la consulta, y solo cuando la restricción generada se puede usar junto con una restricción de columna posterior proveniente del predicado de la consulta).
Por ejemplo, dado un índice en (x, y) y una condición de consulta
WHERE y = 7700, un escaneo de índice B-tree podría ser
capaz de aplicar la optimización de escaneo por salto. Esto generalmente sucede cuando el
planificador de consultas espera que las búsquedas repetidas de WHERE x = N AND y = 7700
para cada valor posible de N (o para cada
valor de x que está realmente almacenado en el índice) sea el
enfoque más rápido posible, dados los índices disponibles en la tabla. Este
enfoque generalmente solo se toma cuando hay tan pocos valores distintos de
x que el planificador espera que el escaneo salte la
mayor parte del índice (porque la mayoría de sus páginas hoja no pueden contener
tuplas relevantes). Si hay muchos valores distintos de x,
entonces se tendrá que escanear todo el índice, por lo que en la mayoría de los casos el planificador
preferirá un escaneo secuencial de la tabla en lugar de usar el índice.
La optimización de escaneo por salto también se puede aplicar de forma selectiva, durante escaneos B-tree
que tienen al menos algunas restricciones útiles del predicado de la consulta.
Por ejemplo, dado un índice en (a, b, c) y una
condición de consulta WHERE a = 5 AND b >= 42 AND c < 77,
es posible que el índice deba escanearse desde la primera entrada con
a = 5 y b = 42 hasta la última
entrada con a = 5. Las entradas de índice con
c >= 77 nunca necesitarán filtrarse a nivel de tabla,
pero puede ser o no provechoso saltar sobre ellas dentro del
índice. Cuando se produce el salto, el escaneo inicia una nueva búsqueda en el índice para
reposicionarse desde el final de la agrupación actual de a = 5 y
b = N (es decir, desde la posición en el índice
donde aparece la primera tupla a = 5 AND b = N AND c >= 77),
hasta el inicio de la siguiente agrupación (es decir, la posición en el
índice donde aparece la primera tupla a = 5 AND b = N + 1).
Un índice GiST multicolumna se puede usar con condiciones de consulta que involucren cualquier subconjunto de las columnas del índice. Las condiciones en columnas adicionales restringen las entradas devueltas por el índice, pero la condición en la primera columna es la más importante para determinar qué parte del índice debe escanearse. Un índice GiST será relativamente ineficaz si su primera columna tiene solo unos pocos valores distintos, incluso si hay muchos valores distintos en las columnas adicionales.
Un índice GIN multicolumna se puede usar con condiciones de consulta que involucren cualquier subconjunto de las columnas del índice. A diferencia de B-tree o GiST, la efectividad de la búsqueda del índice es la misma independientemente de qué columna(s) de índice utilicen las condiciones de la consulta.
Un índice BRIN multicolumna se puede usar con condiciones de consulta que
involucren cualquier subconjunto de las columnas del índice. Al igual que GIN y a diferencia de B-tree o
GiST, la efectividad de la búsqueda del índice es la misma independientemente de qué columna(s) de índice
utilicen las condiciones de la consulta. La única razón para tener múltiples índices BRIN
en lugar de un solo índice BRIN multicolumna en una sola tabla es tener
un parámetro de almacenamiento pages_per_range diferente.
Por supuesto, cada columna debe usarse con operadores apropiados para el tipo de índice; no se considerarán las cláusulas que involucren otros operadores.
Los índices multicolumna deben usarse con moderación. En la mayoría de las situaciones, un índice en una sola columna es suficiente y ahorra espacio y tiempo. Es poco probable que los índices con más de tres columnas sean útiles a menos que el uso de la tabla esté extremadamente estilizado. Consulta también Section 11.5 y Section 11.9 para una discusión sobre los méritos de las diferentes configuraciones de índices.