2010-12-02 27 views
59

¿Qué sucede si un índice agrupado no es único? ¿Puede llevar a un mal rendimiento porque las filas insertadas fluyen a una página de "desbordamiento" de algún tipo?¿Los índices agrupados tienen que ser únicos?

¿Es "hecho" único y en caso afirmativo cómo? ¿Cuál es la mejor manera de hacerlo único?

Pregunto porque actualmente estoy usando un índice agrupado para dividir mi tabla en partes lógicas, pero el rendimiento es regular, y recientemente obtuve the advice para hacer que mis índices agrupados sean únicos. Me gustaría una segunda opinión sobre eso.

Gracias!

Respuesta

66

No tienen tienen para ser único pero ciertamente se recomienda.
Aún no he encontrado un escenario en el que desee crear un elemento de configuración en una columna no única.

¿Qué pasa si create a CI on a non-unique column

Si el índice agrupado no es una única índice, SQL Server hace ningún duplicados de las llaves únicas añadiendo un internamente valor generado llamado uniqueifier

¿Esto lleva a un mal rendimiento?

Agregar un singularizador ciertamente agrega un poco de sobrecarga en el cálculo y en el almacenamiento.
Si esta sobrecarga será notada depende de varios factores.

  • Cuantos datos contiene la tabla.
  • Cuál es la tasa de inserciones.
  • ¿Con qué frecuencia se usa el CI en una selección (cuando no existen índices de cobertura, casi siempre).

Editar
como se ha señalado por Remus en los comentarios, sí existen casos de uso en la creación de un CI no único sería una opción razonable. El hecho de que no haya encontrado uno de esos escenarios simplemente muestra mi propia falta de exposición o competencia (escoja su elección).

+21

1 causa todo lo que dice es correcto, pero sólo quería añadir: CI no único son bastante comunes cuando escaneo de rangos en particular, la columna (no único) es el acceso frecuente patrón. –

+0

@Remus Rusanu: * * * * estaba pensando en agregar un descargo a mi declaración de escenario como * pero eso no significa nada *. Gracias por señalar un escenario donde podría ser útil. –

+4

@Remus: ¿te refieres a la situación de nicho en la que tienes una columna no exclusiva como 'Departmentid' donde consultas algo como 'DepartmentId BETWEEN 1 and 100'? * editar * ah veo lo que quieres decir, sí, una columna de fecha en una tabla de registro también es un buen ejemplo. – thomaspaulb

8

¿Los índices agrupados tienen que ser únicos?

No, y hay momentos en que es mejor si no lo son.

Considere una mesa con un EmployeeId semi-aleatoria, única, y una DepartmentID para cada empleado: si su instrucción de selección es

SELECT * FROM EmployeeTable WHERE DepartmentId=%DepartmentValue% 

entonces es mejor para el rendimiento si el DepartmentId es el índice agrupado a pesar de que (o incluso especialmente porque) no es el índice único (mejor para el rendimiento porque asegura que todos los registros dentro de un DepartmentId determinado están agrupados).


¿Tiene alguna referencia?

Hay Clustered Index Design Guidelines por ejemplo, lo que dice,

Con pocas excepciones, todas las mesas debe tener un índice agrupado define en la columna o columnas, que ofrecen lo siguiente:

  • Se puede usar para consultas de uso frecuente.
  • Proporcionan un alto grado de exclusividad.
  • Se puede usar en consultas de rango.

Mi comprensión de "alto grado de singularidad", por ejemplo, es que no es bueno para elegir "País", como el índice clusted si la mayoría de sus consultas quieren seleccionar los registros dentro de una población dada.

+0

Sí, eso es lo que pensé hasta ahora, pero también recibo el consejo exactamente opuesto, así que me pregunto cuál es la verdad. ¿Tienes alguna referencia? – thomaspaulb

+0

@littlegreen Edité mi respuesta para intentar responder a su pregunta. – ChrisW

+0

Gracias. Sí, está bien, veo tu punto. Pero si inserta regularmente un país completo a la vez, un índice agrupado en (país, ciudad) me parecería engorroso, ya que requiere clasificar los datos. Por otro lado, un ordenamiento antes del inserto no sería tan problemático ... – thomaspaulb

18

me gusta de revisar lo que la Reina de la indización, Kimberly Tripp, tiene que decir sobre el tema:

voy a comenzar con mi recomendación para la clave de agrupación - por un par de razones. En primer lugar, es una decisión fácil de tomar y, en segundo lugar, tomar esta decisión a tiempo ayuda a prevenir de forma proactiva algunos tipos de fragmentación. Si puede evitar ciertos tipos de fragmentación de la tabla base, entonces puede minimizar algunas actividades de mantenimiento (algunas de las cuales, en SQL Server 2000 Y menos de las cuales, en SQL Server 2005) requieren que su tabla esté fuera de línea. OK, voy a llegar a las cosas de la reconstrucción posterior .....

Vamos a empezar con las cosas importantes que busco en una clave de agrupación:

* Unique 
* Narrow 
* Static 

Por qué es único? Una clave de clúster debe ser única porque una clave de clúster (cuando existe) se utiliza como la clave de búsqueda de todos los índices no agrupados. Tomemos, por ejemplo, un índice en la parte posterior de un libro; si necesita encontrar los datos a los que apunta una entrada de índice, esa entrada (la entrada de índice) debe ser única; de lo contrario, qué entrada de índice sería la que está buscando. ? Entonces, cuando crea el índice agrupado, debe ser único. Pero, SQL Server no requiere que su clave de clúster se cree en una columna única. Puede crearlo en cualquier columna que desee. Internamente, si la clave de clúster no es única, SQL Server la "uniquificará" al agregar un entero de 4 bytes a los datos. Entonces, si el índice agrupado se crea en algo que no es único, no solo hay una sobrecarga adicional en la creación del índice, hay espacio en el disco desperdiciado, costos adicionales en INSERTES y ACTUALIZACIONES, y en SQL Server 2000, hay un costo adicional en un índice clustereD reconstruir (lo cual es más probable debido a la mala elección de la clave de agrupamiento).

Fuente:Ever-increasing clustering key debate - again!

+10

+1 por presentarme a la reina de la indexación :-) – thomaspaulb

+0

Sin embargo, una pregunta es que la Reina recomienda una nueva secuencia para uniquify los datos, pero SQL Server genera su propio uniquifier si no lo especifica. ¿Todavía hay alguna razón para agregar su propia identificación secuencial? – thomaspaulb

+1

@littlegreen: ella dice que si insiste en usar los GUID (que son realmente muy malos para su uso en un índice de clúster), al menos use 'newsequentialid()' para obtener un GUID casi secuencializado. Pero sí: si ** usted ** agrega su propia identificación única (yo siempre prefiero INT IDENTIDAD), entonces tiene ese valor a mano, y puede usarlo (por ejemplo, para establecer una relación FK). Los archivos únicos de SQL Server son invisibles para usted y, por lo tanto, solo son gastos generales que no puede usar. –

Cuestiones relacionadas