unico una tener puede nonclustered nomenclatura indice estructura ejemplos diseño datos cuantos clustered agrupados sql-server guid clustered-index

sql server - una - ¿Debería deshacerme de los índices agrupados en las columnas Guid?



indices sql server (10)

Estoy trabajando en una base de datos que generalmente usa GUID como claves principales.

De forma predeterminada, SQL Server coloca un índice agrupado en columnas de clave principal. Entiendo que esta es una idea tonta para las columnas GUID, y que los índices no agrupados son mejores.

¿Qué piensa? ¿Debería deshacerme de todos los índices agrupados y reemplazarlos por índices no agrupados?

¿Por qué el sintonizador de rendimiento de SQL no ofrecería esto como una recomendación?


Como la mayoría ha mencionado, evite usar un identificador aleatorio en un índice agrupado: no obtendrá los beneficios de la agrupación. En realidad, experimentará una mayor demora. Deshacerse de todos ellos es un consejo sólido. También tenga en cuenta que newsequentialid () puede ser extremadamente problemático en un escenario de replicación de múltiples maestros. Si la base de datos A y B invocan newsequentialid () antes de la replicación, tendrá un conflicto.


Depende de si está haciendo muchas inserciones, o si necesita una búsqueda muy rápida de PK.


El problema con los índices agrupados en un campo GUID es que los GUID son aleatorios, por lo que cuando se inserta un nuevo registro, una parte importante de los datos en el disco debe moverse para insertar los registros en el medio de la tabla.

Sin embargo, con índices agrupados basados ​​en enteros, los enteros son normalmente secuenciales (como con una especificación de IDENTITY ), por lo que solo se agregan al final y no es necesario mover datos.

Por otro lado, los índices agrupados no siempre son malos en los GUID ... todo depende de las necesidades de su aplicación. Si necesita poder SELECT registros rápidamente, entonces use un índice agrupado ... la velocidad INSERT sufrirá, pero la velocidad SELECT se mejorará.


Es casi seguro que desea establecer un índice agrupado en cada tabla en su base de datos. Si una tabla no tiene un índice agrupado, es lo que se conoce como "montón" y el rendimiento de la mayoría de los tipos de consultas comunes es menor para un montón que para una tabla de índice agrupado .

En qué campos debe establecerse el índice agrupado dependen de la tabla en sí y de los patrones de uso esperados de las consultas en la tabla. En casi todos los casos, probablemente desee que el índice agrupado esté en una columna o una combinación de columnas que sea única, es decir, (una clave alternativa), porque si no lo es, SQL agregará un valor único al final de cualquier campos que selecciona de todos modos. Si su tabla tiene una columna o columnas que las consultas utilizarán con frecuencia para seleccionar o filtrar registros múltiples (por ejemplo, si su tabla contiene transacciones de ventas, y su aplicación frecuentemente solicitará transacciones de ventas por ID de producto, o incluso mejor, una tabla de detalles de la factura, donde en casi todos los casos estará recuperando todos los registros de detalles para una factura específica, o una tabla de facturas donde a menudo recupera todas las facturas de un cliente en particular ... Esto es cierto independientemente de que sea seleccionado como grande números de registros por un solo valor, o por un rango de valores)

Estas columnas son candidatas para el índice agrupado. El orden de las columnas en el índice agrupado es crítico. La primera columna definida en el índice debe ser la columna que se seleccionará o filtrará primero en las consultas esperadas.

El motivo de todo esto se basa en comprender la estructura interna de un índice de base de datos. Estos índices se denominan índices de árbol equilibrado (árbol B). son como un árbol binario, excepto que cada nodo en el árbol puede tener un número arbitrario de entradas (y nodos secundarios), en lugar de solo dos. Lo que hace que un índice agrupado sea diferente es que los nodos hoja en un índice agrupado son las páginas de datos reales del disco físico de la tabla. mientras que los nodos hoja del índice no agrupado simplemente "apuntan" a las páginas de datos de las tablas.

Cuando una tabla tiene un índice clsutered, por lo tanto, las páginas de datos de las tablas son el nivel de hoja de ese índice, y cada una tiene un puntero a la página anterior y la siguiente en el orden de índice (forman una lista doblemente enlazada) .

Entonces, si su consulta solicita un rango de filas que está en el mismo orden que el índice agrupado ... el procesador solo tiene que recorrer el índice una vez (o quizás dos veces) para encontrar la página de inicio de los datos y luego seguir el punteros de lista vinculados para pasar a la página siguiente y a la página siguiente, hasta que haya leído todas las páginas de datos que necesita.

Para un índice no agrupado, tiene que atravesar el índice una vez por cada fila que recupera ...

NOTA: EDITAR
Para abordar el problema secuencial de las columnas clave clave, tenga en cuenta que SQL2k5 tiene NEWSEQUENTIALID () que de hecho genera las guías de la forma secuencial "antigua".

o puede investigar el algoritmo de guiado Jimmy Nielsens COMB que se implementa en el código del lado del cliente:

COMB Guids



Sí, debe eliminar el índice agrupado en las claves principales GUID por los motivos que Galwegian menciona más arriba. Hemos hecho esto en nuestras aplicaciones.


Sí, no tiene sentido tener un índice agrupado en un valor aleatorio.

Probablemente quiera índices agrupados EN ALGÚN LUGAR en su base de datos. Por ejemplo, si tiene una tabla de "Autor" y una tabla de "Libro" con una clave externa para "Autor", y si tiene una consulta en su aplicación que diga, "seleccione ... de Libro donde AuthorId = .. ", entonces estarías leyendo una serie de libros. Será más rápido si esos libros están físicamente uno al lado del otro en el disco, de modo que la cabeza del disco no tenga que rebotar de un sector a otro reuniendo todos los libros de ese autor.

Entonces, debe pensar en su aplicación, las formas en que consulta la base de datos.

Haz los cambios.

Y luego prueba, porque nunca se sabe ...


Si bien la agrupación en un GUID normalmente es una mala idea, tenga en cuenta que los GUID pueden, en algunas circunstancias, causar fragmentación incluso en índices no agrupados .

Tenga en cuenta que si está utilizando SQL Server 2005, la función newsequentialid () produce GUID secuenciales . Esto ayuda a prevenir el problema de la fragmentación.

Sugiero usar una consulta SQL como la siguiente para medir la fragmentación antes de tomar cualquier decisión (excusa la sintaxis no ANSI):

SELECT OBJECT_NAME (ips.[object_id]) AS ''Object Name'', si.name AS ''Index Name'', ROUND (ips.avg_fragmentation_in_percent, 2) AS ''Fragmentation'', ips.page_count AS ''Pages'', ROUND (ips.avg_page_space_used_in_percent, 2) AS ''Page Density'' FROM sys.dm_db_index_physical_stats (DB_ID (''MyDatabase''), NULL, NULL, NULL, ''DETAILED'') ips CROSS APPLY sys.indexes si WHERE si.object_id = ips.object_id AND si.index_id = ips.index_id AND ips.index_level = 0;


Si está utilizando NewId (), puede cambiar a NewSequentialId (). Eso debería ayudar a la inserción perf.


Una razón importante para un índice agrupado es cuando a menudo desea recuperar filas para un rango de valores para una columna determinada. Debido a que los datos se organizan físicamente en ese orden, las filas se pueden extraer de manera muy eficiente.

Algo como un GUID, aunque es excelente para una clave principal, podría ser perjudicial para el rendimiento, ya que habrá costos adicionales para las inserciones y ningún beneficio perceptible en las selecciones.

Entonces sí, no agrupe un índice en GUID.

En cuanto a por qué no se ofrece como recomendación, sugiero que el sintonizador sea consciente de este hecho.