10

Normalmente, el índice agrupado se crea en SQL Server Management Studio configurando la clave principal; sin embargo, mi pregunta reciente sobre PK < -> índice agrupado (Meaning of Primary Key to Microsoft SQL Server 2008) ha demostrado que no es necesario establecer PK e índice agrupado para que sean iguales.¿Cómo elegir el índice agrupado en SQL Server?

Entonces, ¿cómo debemos elegir los índices agrupados entonces? Vamos a tener el siguiente ejemplo:

crear la tabla Clientes (int Id, ...) crear órdenes de mesa (int Id, int) CustomerID

Normalmente nos crear el PK/CI en ambas columnas ID, pero yo pensado en crearlo para Pedidos en CustomerID. ¿Es esa la mejor opción?

+0

Posible duplicado de [SQL Server: ¿cuándo usar el índice agrupado frente al no agrupado?] (Https://stackoverflow.com/questions/18304376/sql-server-when-to-use-clustered-vs-non- clustered-index) –

Respuesta

11

Según La reina de indexar - Kimberly Tripp - lo que ella busca en un índice agrupado es principalmente:

  • único
  • estrecha
  • estático

Y si usted puede también garantizar:

  • patrón cada vez mayor

entonces está bastante cerca de tener su clave de agrupación ideal!

Eche un vistazo a toda su blog post here, y otra realmente interesante acerca de los impactos clave de la agrupación en operaciones de tabla aquí: The Clustered Index Debate Continues.

Cualquier cosa como una INT (especialmente una INT IDENTIDAD) o posiblemente un INT y un DATETIME son candidatos ideales. Por otros motivos, los GUID no son buenos candidatos en absoluto, por lo que puede tener un GUID como su PK, pero no agrupe su tabla en él; estará fragmentado más allá del reconocimiento y el rendimiento se verá afectado.

+0

¿Estas publicaciones de blog siguen siendo tan relevantes para las versiones más nuevas de SQL Server, o tienen ajustes de rendimiento recientes en SQL Server 2008 y más tarde cambiaron las mejores prácticas de alguna manera? –

+0

@AdrianGrigore: todo sigue siendo válido, siempre que utilice tablas "normales" (por ejemplo, no datawarehouse/columnstore) –

+0

¡Genial, gracias! :) –

1

Si le preocupa la agrupación, generalmente es para ayudar a mejorar la recuperación de datos. En su ejemplo, es probable que desee todos los registros de un cliente determinado a la vez. La agrupación en customerID mantendrá esas filas en la misma página física en lugar de dispersarse en varias páginas de su archivo.

ROT: Cluster en el que desea mostrar una colección de. Las líneas de pedido en una orden de compra son el ejemplo clásico.

+0

Los elementos de línea en un PO pueden ser una buena idea para un clúster, pero no si solo hay 2 o 3 (o una docena) líneas de pedido en el pedido típico. A menos que las filas que está agrupando juntas comiencen a entrar en docenas o cientos, entonces es mejor simplemente dejar que SQL Server realice la búsqueda de marcadores. Tenía un sistema donde el requisito comercial tenía que encontrar todas las "líneas de pedido" que ocurrieron durante el turno de un cajero en particular (para ver si se equilibraban). La desnormalización de las "líneas de pedido" con el 'id' si ** Shift **, y luego la agrupación en ** Shift ** fue un gran aumento de velocidad. –

6

El mejor candidato para un índice CLUSTERED es la clave que usa para referirse a sus registros con mayor frecuencia.

Normalmente, este es un PRIMARY KEY, ya que es lo que se usa en las búsquedas y/o en las relaciones FOREIGN KEY.

En su caso, Orders.ID probablemente participará en las búsquedas y referencias, por lo que es el mejor candidato para ser una expresión de agrupamiento.

Si crea el índice CLUSTERED en Orders.CustomerID, las siguientes cosas suceden:

  1. CustomerID no es única. Para garantizar la exclusividad, se agregará a cada registro una columna oculta especial 32-bit conocida como uniquifier.

  2. Los registros en la tabla se almacenarán de acuerdo con este par de columnas (CustomerID, uniquifier).

  3. Se creará un índice secundario en Order.ID, con (CustomerID, uniquifier) como punteros de registro.

  4. consultas como esta:

    SELECT * 
    FROM Orders 
    WHERE ID = 1234567 
    

    tendrá que hacer una operación externa, una Clustered Seek, ya que no todas las columnas se almacenan en el índice en ID. Para recuperar todas las columnas, el registro primero debe ubicarse en la tabla agrupada.

Esta operación adicional requiere IndexDepth hasta la página se lee como un simple Clustered Seek, la IndexDepth beign O(log(n)) del número total de los registros en la tabla.

Cuestiones relacionadas