Cubriendo índices cuando las columnas adicionales determinados únicamente por el índice agrupado

StackOverflow https://stackoverflow.com/questions/1927399

Pregunta

Supongamos que necesito para actualizar mytab de luTab de la siguiente manera

update myTab
  set LookupVale = (select LookupValue from luTab B
                                       where B.idLookup = myTab.idLookup)

luTab consta de 2 columnas (idLookup (única), LookupValue)

¿Qué es preferible: combinar un índice único agrupado en idLookup, o uno de idLookup y Lookupvalue? Es un índice de cobertura va a hacer ninguna diferencia en esta situación?

(estoy sobre todo interesado en el servidor SQL)


Epílogo:

he seguido pruebas Krips abajo con filas 27M en MyTab, 1,5 M filas en luTab. La parte crucial parece ser la unicidad del índice. Si no se especifica el índice como única, la actualización utiliza una tabla hash. Si no se especifica como único, entonces la actualización aggreates primera luTab por idLookup (la Corriente Aggegate) y luego utiliza un bucle anidado. Esto es mucho más lento. Cuando utilizo el índice extendido, SQL es ahora ya no assued que que LookupValue es único por lo que su forzado por la mucho más lento, corriente ruta bucle agregado-anidada

¿Fue útil?

Solución

He creado las tablas y cargado a pocos registros (50 o más operaciones de búsqueda, y 15 en mytab).

A continuación, he intentado varias opciones de índice. El Índice de Seek en luTab siempre tiene un costo de 29%.

La parte interesante es que si se añade a la columna de la LookupValue al índice de luTab el plan de ejecución muestra dos pasos adicionales después de la búsqueda de índice: Secuencia del agregado y hacer valer. Mientras que el coste es 0%, que pueden subir con más datos.

También he intentado un índice no agrupado en un solo idLookup, e incluyendo LookupValue como una 'columna Incluido'. De esa manera las páginas de datos no necesitan tener acceso a recuperar esa esa columna. Eso puede ser una opción para usted, aunque el plan de ejecución no muestra nada diferente (pero que no tienen la Corriente Gravilla / Assert tampoco).

-Krip

Otros consejos

En primer lugar:

  • Un índice de recubrimiento está siempre no agrupado
  • Siempre debe tener un PK y un índice agrupado (no son los mismos de forma predeterminada en SQL Server)

Los 2 conceptos están separados

Así que:

  • Su PK (agrupado) sería idLookup si esto identifica de forma única una fila
  • El índice de cobertura sería (idLookup) incluyen (LookupValue)

Sin embargo:

  • idLookup es el PK (agrupado), por lo que no es necesario un índice de cobertura
  • el índice agrupado (PK) está implícitamente "cobertura" por la naturaleza de un índice agrupado (simplemente, el índice es de datos en el nivel más bajo)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top