Estaba leyendo Clustered
y Non Clustered Indexes
.
Clustered Index
- Contiene páginas de datos. Eso significa que la información completa de la fila estará presente en la columna de índice agrupado.
Non Clustered Index
- Solo contiene la información del Localizador de filas en forma de columna Índice agrupado (si está disponible) o el Identificador de archivo + Número de página + Total de filas en una página. Esto significa que el motor de consulta debe dar un paso adicional para localizar los datos reales.
Consulta : ¿cómo puedo verificar la diferencia de rendimiento con la ayuda de un ejemplo práctico, ya que sabemos que la tabla solo puede tener uno Clustered Index
y proporciona sorting
en el Clustered Index Column
y Non Clustered Index
no proporciona sorting
y puede admitir 999 Non Clustered Indexes
in SQL Server 2008
y 249 in SQL Server 2005
.
Respuestas:
Muy buena pregunta ya que es un concepto tan importante. Sin embargo, este es un gran tema y lo que voy a mostrar es una simplificación para que pueda comprender los conceptos básicos.
En primer lugar, cuando ve una tabla de pensamiento de índice agrupado . En el servidor SQL, si una tabla no contiene un índice agrupado, es un montón. Crear un índice agrupado en la tabla en realidad transforma la tabla en una estructura tipo b-tree. Su índice agrupado ES su tabla, no está separado de la tabla
¿Alguna vez se preguntó por qué solo puede tener un índice agrupado? Bueno, si tuviéramos dos índices agrupados necesitaríamos dos copias de la tabla. Contiene los datos después de todo.
Voy a tratar de explicar esto usando un ejemplo simple.
NOTA: Creé la tabla en este ejemplo y la llené con más de 3 millones de entradas aleatorias. Luego ejecutó las consultas reales y pegó los planes de ejecución aquí.
Lo que realmente necesita comprender es la notación O o la eficiencia operativa . Supongamos que tiene la siguiente tabla.
Entonces, aquí tenemos una tabla básica con una clave agrupada en CustomerID (la clave principal está agrupada de forma predeterminada). Por lo tanto, la tabla se organiza / ordena en función de la clave principal CustomerID. Los niveles intermedios contendrán los valores de CustomerID. Las páginas de datos contendrán la fila completa, por lo tanto, es la fila de la tabla.
También crearemos un índice no agrupado en el campo CustomerName. El siguiente código lo hará.
Entonces, en este índice, encontrará en las páginas de datos / nodos de nivel de hoja un puntero a los niveles intermedios en el índice agrupado. El índice se organiza / ordena alrededor del campo CustomerName. Por lo tanto, el nivel intermedio contiene los valores de CustomerName y el nivel de hoja contendrá el puntero (estos valores de puntero son en realidad los valores de clave principal o la columna CustomerID).
Correcto, si ejecutamos la siguiente consulta:
SQL probablemente leerá el índice agrupado a través de una operación de búsqueda. Una operación de búsqueda es una búsqueda binaria que es mucho más eficiente que una exploración que es una búsqueda secuencial. Entonces, en nuestro ejemplo anterior, se lee el índice y, mediante una búsqueda binaria, SQL puede eliminar los datos que no coinciden con los criterios que estamos buscando. Vea la captura de pantalla adjunta para el plan de consulta.
Entonces, el número de operaciones o la notación O para la operación de búsqueda es la siguiente:
Entonces son dos operaciones. Sin embargo, si ejecutamos la siguiente consulta:
SQL ahora usará el índice no agrupado en CustomerName para realizar la búsqueda. Sin embargo, dado que este es un índice no agrupado, no contiene todos los datos de la fila.
Por lo tanto, SQL realizará la búsqueda en los niveles intermedios para encontrar los registros que coinciden y luego realizará una búsqueda utilizando los valores devueltos para realizar otra búsqueda en el índice agrupado (también conocido como la tabla) para recuperar los datos reales. Esto suena confuso, lo sé, pero sigue leyendo y todo quedará claro.
Dado que nuestro índice no agrupado solo contiene el campo CustomerName (los valores de campo indexados almacenados en los nodos intermedios) y el puntero a los datos que es CustomerID, el índice no tiene registro del CustomerSurname. El CustomerSurname se debe obtener del índice o la tabla agrupados.
Cuando ejecuto esta consulta obtengo el siguiente plan de ejecución:
Hay dos cosas importantes que debes notar en la captura de pantalla anterior
¿Por qué SQL vuelve a sugerir el índice en CustomerName? Bueno, dado que el índice contiene solo el CustomerID y el CustomerName SQL todavía tiene que encontrar el CustomerSurname de la tabla / índices agrupados.
Si creáramos el índice e incluyéramos la columna CustomerSurname en el índice, SQL podría satisfacer la consulta completa simplemente leyendo el índice no agrupado. Es por eso que SQL sugiere que cambie mi índice no agrupado.
Aquí puede ver la operación adicional que SQL debe hacer para obtener la columna CustomerSurname de la clave agrupada
Por lo tanto, el número de operaciones es el siguiente:
Eso son 4 operaciones para obtener los valores. El doble de la cantidad de operaciones necesarias en comparación con la lectura del índice agrupado. Le muestra que su índice agrupado es su índice más poderoso, ya que contiene todos los datos.
Tan solo para aclarar un último punto. ¿Por qué digo que el puntero en el índice no agrupado es el valor de la clave primaria? Bueno, para demostrar que los nodos de nivel de hoja del índice no agrupado contienen el valor de la clave primaria, cambio mi consulta a:
En esta consulta, SQL puede leer el CustomerID del índice no agrupado. No necesita hacer una búsqueda en el índice agrupado. Esto se puede ver en el plan de ejecución que se ve así.
Observe la diferencia entre esta consulta y la consulta anterior. No hay búsqueda. SQL puede encontrar todos los datos en el índice no agrupado
Esperemos que pueda comenzar a comprender que el índice agrupado es la tabla y los índices no agrupados NO contienen todos los datos. La indexación acelerará las selecciones debido al hecho de que se pueden realizar búsquedas binarias, pero solo los índices agrupados contienen todos los datos. Por lo tanto, una búsqueda en un índice no agrupado casi siempre dará como resultado que los valores se carguen desde el índice agrupado. Estas operaciones adicionales hacen que los índices no agrupados sean menos eficientes que un índice agrupado.
Espero que esto aclare las cosas. Si algo no tiene sentido, publique un comentario e intentaré aclararlo. Es bastante tarde aquí y mi cerebro se siente un poco plano. Tiempo para un toro rojo.
fuente
"Esto significa que el motor de consultas debe dar un paso adicional para localizar los datos reales".
No necesariamente: si el índice está cubriendo una consulta determinada, no se debe realizar ningún viaje a las páginas de datos. Además, con las columnas incluidas, se pueden agregar columnas adicionales a un índice no agrupado para que cubra sin alterar el tamaño de la clave.
Entonces, la respuesta final es: depende (de mucha más información de la que realmente puede cubrir en una sola pregunta): debe comprender todas las capacidades de los índices y el plan de ejecución para una consulta determinada puede diferir de sus expectativas.
Una regla general que tengo es que una tabla siempre tiene un índice agrupado (y generalmente en una identidad o GUID secuencial), pero los índices no agrupados se agregan para el rendimiento. Pero siempre hay excepciones: las tablas de montón tienen un lugar, los índices agrupados más amplios tienen un lugar. Los índices aparentemente redundantes que son más estrechos para ajustarse a más filas por página tienen un lugar. etcétera etcétera.
Y no me preocuparía por los límites en los diversos índices permitidos; eso seguramente no entrará en juego en muchos ejemplos del mundo real.
fuente
there are always exceptions
- demasiadas personas omiten esto y piensan que cada índice agrupado debería ser unint identity
no importa qué.