¿Importa el orden de las columnas en un índice PK?
Si lo hace
De manera predeterminada, la restricción de clave principal se aplica en SQL Server mediante un índice agrupado único. El índice agrupado define el orden lógico de las filas en la tabla. Puede haber una cantidad de páginas de índice adicionales agregadas para representar los niveles superiores del índice b-tree, pero el nivel más bajo (hoja) de un índice agrupado es simplemente el orden lógico de los datos en sí.
Para que quede claro, las filas de una página no están necesariamente almacenadas físicamente en orden de clave de índice agrupado. Hay una estructura de indirección separada dentro de la página que almacena un puntero a cada fila. Esta estructura está ordenada por las claves de índice agrupadas. Además, cada página tiene un puntero a la página anterior y siguiente en el mismo nivel en orden de clave de índice agrupado.
Con una clave primaria agrupada de (RowNumber, DataDate)
, las filas se ordenan lógicamente primero por RowNumber
y luego por DataDate
, de modo que todas las filas donde RowNumber = 1
se agrupan lógicamente, luego las filas donde RowNumber = 2
y así sucesivamente.
Cuando agrega nuevos datos ( RowNumbers
de 1 a n), las nuevas filas pertenecen lógicamente dentro de las páginas existentes, por lo que SQL Server probablemente tendrá que hacer mucho trabajo dividiendo las páginas para hacer espacio. Toda esta actividad genera mucho trabajo adicional (incluido el registro de los cambios) sin ganancia.
Las páginas divididas también comienzan aproximadamente un 50% vacías, por lo que la división excesiva puede dar como resultado una baja densidad de páginas (menos filas que las óptimas por página). Esto no solo es una mala noticia para leer desde el disco (menor densidad = más páginas para leer), sino que las páginas de menor densidad también ocupan más espacio en la memoria cuando se almacenan en caché.
Cambiar el índice agrupado a (DataDate, RowNumber
) significa que los datos nuevos (con, presumiblemente, más altos DataDates
que los almacenados actualmente) se agregan al final lógico del índice agrupado en páginas nuevas. Esto eliminará los gastos generales innecesarios de las páginas divididas y dará como resultado tiempos de carga más rápidos. Los datos menos fragmentados también significan que la actividad de lectura anticipada (leer páginas del disco justo antes de que sean necesarias para una consulta en curso) puede ser más eficiente.
Por lo menos, las consultas son mucho más propensos a buscar en DataDate
que RowNumber
. Un índice agrupado en (DataDate, RowNumber
) admite búsquedas de índice en DataDate
(y luego RowNumber
). La disposición existente solo admite búsquedas en RowNumber
(y solo entonces, tal vez, en DataDate
). Es posible que pueda soltar el índice no agrupado existente DataDate
una vez que se cambie la clave primaria. El índice agrupado será más ancho que el índice no agrupado al que reemplaza, por lo que debe realizar una prueba para asegurarse de que el rendimiento siga siendo aceptable.
Al importar datos nuevos con bcp
, puede obtener un mayor rendimiento si los datos dentro del archivo de importación se ordenan por las claves de índice agrupadas (idealmente (DataDate, RowNumber
) y especifica la bcp
opción:
-h "ORDER(DataDate,RowNumber), TABLOCK"
Para obtener el mejor rendimiento de carga de datos, puede intentar lograr inserciones mínimamente registradas. Para más información, ver:
Sí, el orden es crítico. Dudo mucho que alguna vez consultes por RowNumber (por ejemplo
WHERE RowNumber=1
). De manera abrumadora, las series de tiempo se consultan por date (WHERE DataDate BEWEEN @start AND @end
) y tales consultas requerirían una organización agrupada porDataDate
.La fragmentación en general es un arenque rojo. La reducción de la fragmentación no debería ser su objetivo aquí, pero debería tener una organización adecuada para sus consultas. Además, es bueno tener una fragmentación reducida, pero no es un objetivo en sí mismo. Si tiene un modelo de datos correctamente organizado que coincida con su carga de trabajo (sus consultas están cubiertas adecuadamente) y tiene mediciones que muestran que la fragmentación afecta el rendimiento, entonces podemos hablar de ello.
fuente
WHERE
cláusula en las consultas.