Pregunta

Tengo una pregunta relativa a las mejores prácticas para la indización en SQL Server (o cualquier RDBMS para el caso). Tome la siguiente tabla:

ProfileID int
Text      nvarchar(50)

ProfileID se une a una mesa Profile. Para cada perfil, cada Text debe ser único. Por lo tanto pongo una clave primaria cubierta en ambas columnas. Bien.

Sin embargo, también quiero ser capaz de consultar la tabla anterior por ProfileID. Así que también puse un índice en ProfileID también.

Esto significa que tengo un índice superpuestas. No sé si esto es un total desperdicio ya que no es un índice de la cubierta ya, o si es correcto, ya que el índice de la cubierta sería un hash de las dos columnas (o estoy mal entendido índices de cobertura)?

Editar:

crea el índice en el (ProfileID, Text) orden. ¿Qué pasa si, pongamos por caso, había 3 columnas A, B, y C, que tenía un índice de cobertura sobre los 3. ¿Sería sólo benefician si nos preguntó en contra de "A" o "A, B, y C", pero no "B", o "C", o "B y C"?

¿Fue útil?

Solución

un índice en (ProfileID, Text) (en este orden) es un índice en ProfileID también.

Es posible que aún desee crear un índice adicional sobre ProfileID solamente, si desea un mayor rendimiento SELECT en consultas que no implican Text.

Sin embargo, esto tiene dos inconvenientes:

  1. El mantenimiento de dos índices requiere más recursos y rendimiento de las consultas DML (INSERT, UPDATE, DELETE) pueden sufrir

  2. Si se mezclan las consultas de los dos tipos, ambos índices se ocupan de la memoria caché y no puede haber más fallos de caché que con un solo índice.

    No es un problema si la tabla es lo suficientemente pequeño como para caber en la memoria caché, junto con los dos índices.

El índice de la cubierta sería un hash de las dos columnas (o estoy malentendido índices de cobertura)?

Un índice que cubre realmente sería creada de esta manera:

CREATE INDEX ix_mytable_profile__text ON mytable (ProfileID) INCLUDE (Text)

De esta manera, Text sólo se almacena en los nodos de nivel de hoja del índice.

Sin embargo, ya que se necesita un índice UNIQUE, ambas columnas tienen que ser parte de la clave. Los nodos están ordenadas lexicográficamente en ProfileID entonces Text.

crea el índice en el orden (ProfileID de, texto). ¿Qué pasa si, pongamos por caso, había 3 columnas A, B, y C, que tenía un índice de cobertura sobre los 3. ¿Sería sólo benefician si nos preguntó en contra de "A" o "A, B, y C", pero no "B", o "C", o "B y C"?

CREATE INDEX ix_mytable_a_b_c ON mytable (a, b, c)

SELECT  a, b, с
FROM    mytable
WHERE   a = 1 

-- Index lookup, no table lookup. a is leading

SELECT  a, b, с
FROM    mytable
WHERE   a = 1
        AND b = 1

-- Index lookup, no table lookup. (a, b) are leading.

SELECT  a, b, с
FROM    mytable
WHERE   b = 1

-- Index full scan (`b` is not leading), no table lookup

SELECT  a, b, с
FROM    mytable
WHERE   c = 1

-- Index full scan (`c` is not leading), no table lookup

SELECT  a, b, с, d
FROM    mytable
WHERE   a = 1

-- Index lookup, table tookup (d is not a part of the index).

SELECT  a, b, с, d
FROM    mytable
WHERE   b = 1

-- Table full scan (there is no point in using index at all, neither for lookup nor for covering).
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top