La pregunta no es "cuándo debería ser PK", sino que debería preguntarse "¿cuál es la clave adecuada para el índice agrupado"?
Y la respuesta realmente depende de cómo se consultan los datos . El índice agrupado tiene una ventaja sobre todos los demás índices: dado que siempre incluye todas las columnas, siempre está cubriendo. Por lo tanto, las consultas que pueden aprovechar el índice agrupado ciertamente no necesitan usar búsquedas para satisfacer algunas de las columnas y / o predicados proyectados.
Otra pieza del rompecabezas es cómo se puede usar un índice . Hay tres patrones típicos:
- sondeos, cuando se busca un único valor clave en el índice
- escaneos de rango, cuando se recupera un rango de valores clave
- ordenar por requisitos, cuando un índice puede satisfacer un pedido sin requerir un orden de parar y continuar
Entonces, si analiza su carga esperada (las consultas) y descubre que una gran cantidad de consultas usaría un índice particular porque usan un cierto patrón de acceso que se beneficia de un índice, tiene sentido proponer ese índice como el índice agrupado.
Otro factor más es que la clave de índice agrupada es la clave de búsqueda utilizada por todos los índices no agrupados y, por lo tanto, una clave de índice agrupada amplia crea un efecto dominó y amplía todos los índices no agrupados y los índices amplios significan más páginas, más E / S , más memoria, menos bondad.
Un buen índice agrupado es estable , no cambia durante la vida útil de la entidad, porque un cambio en los valores clave del índice agrupado significa que la fila debe eliminarse e insertarse nuevamente.
Y un buen índice agrupado crece en orden no al azar (cada valor de clave recién insertado es mayor que el valor anterior) para evitar divisiones de página y fragmentación (sin perder el tiempo con FILLFACTOR
s).
Entonces, ahora que sabemos qué es una buena clave de índice agrupada, ¿la clave primaria (que es una propiedad lógica de modelado de datos) cumple con los requisitos? En caso afirmativo, entonces el PK debe agruparse. Si no, entonces la PK no debe estar agrupada.
Para dar un ejemplo, considere una tabla de hechos de ventas. Cada entrada tiene una ID que es la clave principal. Pero la gran mayoría de las consultas solicitan datos entre una fecha y otra fecha, por lo tanto, la mejor clave de índice agrupada sería la fecha de venta , no la ID . Otro ejemplo de tener un índice agrupado diferente de la clave primaria es una clave de selectividad muy baja, como una 'categoría' o un 'estado', una clave con muy pocos valores distintos. Tener una clave de índice agrupada con esta clave de baja selectividad como la tecla más a la izquierda, por ejemplo (state, id)
, a menudo tiene sentido debido a los escaneos de rangos que buscan todas las entradas en un "estado" particular.
Una última nota sobre la posibilidad de una clave primaria no agrupada sobre un montón (es decir, no hay ningún índice agrupado). Este puede ser un escenario válido, la razón típica es cuando el rendimiento de inserción masiva es crítico, ya que los montones tienen un rendimiento de inserción masiva significativamente mejor en comparación con los índices agrupados.
(state, id)
. En este ejemplo, el requisito de "buen índice agrupado crece en orden no al azar" no se cumplirá, ¿no es así? Entonces, ¿podemos considerarlo como un buen índice agrupado?La razón básica para usar índices agrupados se establece en Wikipedia :
Digamos que tengo una tabla de personas, y estas personas tienen una columna de país y una clave primaria única. Es una tabla demográfica, así que estas son las únicas cosas que me importan; qué país y cuántas personas únicas están vinculadas a ese país.
Por lo tanto, solo es probable que SELECCIONE DONDE O PEDIR POR la columna País; un índice agrupado en la clave primaria no me sirve de nada, no estoy accediendo a estos datos por PK, estoy accediendo a ellos por esta otra columna. Como solo puedo tener un índice agrupado en una tabla, declarar mi PK como Agrupado me impediría usar un Índice agrupado en el país.
Además, aquí hay un buen artículo sobre índices agrupados vs índices no agrupados, resulta que los índices agrupados causaron problemas de rendimiento de inserción en SQL Server 6.5 (que al menos con suerte no es relevante para la mayoría de nosotros aquí).
Tenga en cuenta que este no es el caso en versiones posteriores.
fuente
Si su clave principal es de
UNIQUEIDENTIFIER
, asegúrese de especificar que esNONCLUSTERED
. Si lo agrupa, cada inserción tendrá que hacer una combinación de registros para insertar la nueva fila en la posición correcta. Esto hará que el rendimiento del tanque.fuente
UNIQUEIDENTIFIER
También existe un tipo secuencial y tiene la misma probabilidad de generar claves únicas, aunque todavía tiene un tamaño de 128.Un ejemplo muy común:
Customer
mesa conCustomerID
comoCLUSTERED PRIMARY KEY
OrderID (PK), CustomerID, OrderDate
y algunas otras columnasOrderPositions
conOrderPositionID (PK), OrderId, ProductID, Amount, Price ...
Por supuesto, "depende" es, como casi siempre, la respuesta correcta, pero la mayoría de las aplicaciones (no BI-Reports) funcionarán en función del cliente (por ejemplo, inicie sesión como cliente 278 en el sitio web y haga clic en "Mis pedidos" o el secretario enumera todos los pedidos del cliente 4569 o su rutina de facturación resumirá todos los pedidos del cliente 137).
En este caso, no tendría mucho sentido agrupar la tabla por
OrderID
. Sí, tendrá consultasSELECT ... WHERE OrderId = ?
para enumerar los detalles del pedido, pero esto generalmente sería una búsqueda de índice corta y barata (3 lecturas).Por otro lado, si agrupara su
Order
tabla porCustomerID
, no tendría que hacer múltiples búsquedas de claves cada vez que consulta la tablaCustomerId = ?
.El
CLUSTERED INDEX
debe haber siempreUNIQUE
, de lo contrario SQL Server añadiría una (= inservible) columna INT invisibleUNIQUIFIER
para asegurar la uniquiness - y sería mucho más sentido para agregar datos reales (utilizables) a continuación algunas cosas al azar (en función del orden de inserción).Debido a que un cliente (con suerte) realizará más de un pedido, tendremos que agregar el
OrderID
o (si normalmente ordena esto) elOrderDate
(si es una fecha y hora; de lo contrario, el cliente estaría limitado a un pedido por día) a elCLUSTERED INDEX
y terminar con:CREATE UNIQUE CLUSTERED INDEX IX_Orders_UQ on Orders (CustomerID, OrderID)
Las mismas reglas se aplican a la
OrderPositions
tabla. Por lo general, la mayoría de las consultas enumerarán todas las posiciones para un orden específico, por lo que debe crear el PK con elOrderPositionID
asNONCLUSTERED
yUNIQUE CLUSTERED INDEX
el aOrderId, OrderPositionID
.Por cierto: es correcto que la
Customer
tabla esté agrupada por su PK (laCustomerID
, porque es una "Tabla de nivel superior" y, en una aplicación típica, será consultada principalmente por su CustomerID.Las tablas de búsqueda puras como eg
Genders
oInvoiceTypes
orPaymentType
son otro ejemplo de tablas que deberían estar agrupadas por su PK (porque normalmente las unirás enGenderId
,InvoiceTypeId
oPaymentTypeId
).fuente
Cuando se considera que un índice agrupado es más beneficioso para el sistema en general que una PK agrupada mediante el uso de alguna medida de rendimiento. Solo puede haber un índice agrupado en una tabla.
Ejemplos de medidas de rendimiento son el tiempo de consulta único (velocidad), la integración de los tiempos de consulta totales contra la tabla (eficiencia) y la necesidad de agregar muchas columnas de inclusión a un índice no agrupado muy grande para lograr un rendimiento similar al agrupado (tamaño )
Esto puede suceder cuando los datos generalmente se recuperan utilizando un índice que no es único, contiene valores nulos (no permitidos en una PK), o la PK se agregó por una razón secundaria (como la replicación o la identificación del registro de seguimiento de auditoría).
fuente