En el almacenamiento orientado a filas de SQL Server, los índices agrupados y no agrupados se organizan como árboles B.
( Fuente de la imagen )
La diferencia clave entre los índices agrupados y los índices no agrupados es que el nivel de hoja del índice agrupado es la tabla. Esto tiene dos implicaciones.
- Las filas en las páginas de hoja de índice agrupadas siempre contienen algo para cada una de las columnas (no dispersas) de la tabla (ya sea el valor o un puntero al valor real).
- El índice agrupado es la copia primaria de una tabla.
Los índices no agrupados también pueden hacer el punto 1 mediante el uso de la INCLUDE
cláusula (desde SQL Server 2005) para incluir explícitamente todas las columnas sin clave, pero son representaciones secundarias y siempre hay otra copia de los datos (la tabla en sí).
CREATE TABLE T
(
A INT,
B INT,
C INT,
D INT
)
CREATE UNIQUE CLUSTERED INDEX ci ON T(A,B)
CREATE UNIQUE NONCLUSTERED INDEX nci ON T(A,B) INCLUDE (C,D)
Los dos índices anteriores serán casi idénticos. Con las páginas de índice de nivel superior que contienen valores para las columnas clave A,B
y las páginas de nivel de hoja que contienenA,B,C,D
Solo puede haber un índice agrupado por tabla, porque las filas de datos se pueden ordenar en un solo orden.
La cita anterior de los libros en línea de SQL Server causa mucha confusión
En mi opinión, sería mucho mejor redactado como.
Solo puede haber un índice agrupado por tabla, porque las filas a nivel de hoja del índice agrupado son las filas de la tabla.
La cita en línea de los libros no es incorrecta, pero debe quedar claro que la "clasificación" de los índices agrupados y no agrupados es lógica, no física. Si lee las páginas a nivel de hoja siguiendo la lista vinculada y lee las filas de la página en orden de matriz de ranuras, entonces leerá las filas de índice en orden, pero físicamente las páginas pueden no estar ordenadas. La creencia común de que con un índice agrupado las filas siempre se almacenan físicamente en el disco en el mismo orden que la clave de índice es falsa.
Esta sería una implementación absurda. Por ejemplo, si se inserta una fila en el medio de una tabla de 4 GB, SQL Server no tiene que copiar 2 GB de datos en el archivo para dejar espacio para la fila recién insertada.
En cambio, se produce una división de página. Cada página en el nivel de hoja de los índices agrupados y no agrupados tiene la dirección ( File:Page
) de la página siguiente y anterior en orden de clave lógica. Estas páginas no necesitan ser contiguas o en orden de clave.
por ejemplo, la cadena de páginas enlazadas podría ser 1:2000 <-> 1:157 <-> 1:7053
Cuando se produce una división de página, se asigna una nueva página desde cualquier lugar del grupo de archivos (ya sea de una extensión mixta, para tablas pequeñas o una extensión uniforme no vacía que pertenece a ese objeto o una extensión uniforme recién asignada). Esto podría incluso no estar en el mismo archivo si el grupo de archivos contiene más de uno.
El grado en que el orden lógico y la contigüidad difieren de la versión física idealizada es el grado de fragmentación lógica.
En una base de datos recién creada con un solo archivo, ejecuté lo siguiente.
CREATE TABLE T
(
X TINYINT NOT NULL,
Y CHAR(3000) NULL
);
CREATE CLUSTERED INDEX ix
ON T(X);
GO
--Insert 100 rows with values 1 - 100 in random order
DECLARE @C1 AS CURSOR,
@X AS INT
SET @C1 = CURSOR FAST_FORWARD
FOR SELECT number
FROM master..spt_values
WHERE type = 'P'
AND number BETWEEN 1 AND 100
ORDER BY CRYPT_GEN_RANDOM(4)
OPEN @C1;
FETCH NEXT FROM @C1 INTO @X;
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO T (X)
VALUES (@X);
FETCH NEXT FROM @C1 INTO @X;
END
Luego verificó el diseño de la página con
SELECT page_id,
X,
geometry::Point(page_id, X, 0).STBuffer(1)
FROM T
CROSS APPLY sys.fn_PhysLocCracker( %% physloc %% )
ORDER BY page_id
Los resultados fueron por todas partes. La primera fila en orden de teclas (con valor 1 - resaltada con la flecha a continuación) estaba en casi la última página física.
La fragmentación se puede reducir o eliminar reconstruyendo o reorganizando un índice para aumentar la correlación entre el orden lógico y el orden físico.
despues de correr
ALTER INDEX ix ON T REBUILD;
Tengo lo siguiente
Si la tabla no tiene índice agrupado, se llama montón.
Los índices no agrupados se pueden construir en un montón o en un índice agrupado. Siempre contienen un localizador de filas de vuelta a la tabla base. En el caso de un montón, este es un identificador de fila física (rid) y consta de tres componentes (Archivo: Página: Ranura). En el caso de un índice agrupado, el localizador de filas es lógico (la clave de índice agrupado).
Para el último caso, si el índice no agrupado ya incluye naturalmente la (s) columna (s) clave de CI como columnas de clave NCI o INCLUDE
columnas -d, entonces no se agrega nada. De lo contrario, las columnas clave de CI que faltan se agregan silenciosamente al NCI.
SQL Server siempre garantiza que las columnas clave sean únicas para ambos tipos de índice. Sin embargo, el mecanismo en el que esto se aplica para índices no declarados como únicos difiere entre los dos tipos de índice.
Los índices agrupados obtienen un uniquifier
agregado para cualquier fila con valores clave que duplican una fila existente. Esto es solo un entero ascendente.
Para los índices no agrupados no declarados como únicos, SQL Server agrega silenciosamente el localizador de filas a la clave de índice no agrupada. Esto se aplica a todas las filas, no solo a aquellas que en realidad son duplicadas.
La nomenclatura agrupada frente a la no agrupada también se utiliza para los índices de almacenamiento de columnas. Las mejoras en papel a los estados de almacenamiento de columnas de SQL Server
Aunque los datos del almacén de columnas no están realmente "agrupados" en ninguna clave, decidimos mantener la convención tradicional de SQL Server de referirnos al índice primario como un índice agrupado.