Guid secuencial y fragmentación
-
27-09-2019 - |
Pregunta
Estoy tratando de entender mejor que un GUID y Regular secuencial realiza GUID.
¿Es porque con GUID regular, el índice de utilizar el último byte del GUID a clase? Puesto que es al azar que hará que una gran cantidad de fragmentación y de página se divide ya que a menudo se moverá de datos a otra página para insertar nuevos datos?
secuencial GUID sinusoidal es secuencial que causará mucho menos divisiones de página y la fragmentación?
Es mi entendimiento correcto?
Si alguien puede arrojar más luces sobre el tema, te aprecia mucho.
Gracias
EDIT:
secuencial GUID = NEWSEQUENTIALID (),
Regular GUID = NEWID ()
Solución
Usted ha dicho casi todo en su pregunta.
Con un GUID secuencial / primarias filas nuevas claves se sumarán al final de la tabla, lo que hace las cosas bien para un fácil servidor SQL. En comparación al azar mediante claves primarias que los nuevos registros podrían ser insertados en cualquier lugar de la tabla - la posibilidad de que la última página de la tabla que se está en la memoria caché es bastante probable (si es allí donde todas las lecturas van), sin embargo, la posibilidad de una página al azar en el centro de la mesa está en la memoria caché es bastante bajo, lo que significa IO adicional que se requiere.
Además de eso, al insertar filas en el centro de la mesa existe la posibilidad de que no hay suficiente espacio para insertar la fila adicional. Si este es el caso, entonces las necesidades de servidor SQL para realizar operaciones de IO caros adicionales con el fin de crear espacio para el registro - la única manera de evitar esto es tener huecos esparcidos entre los datos para tener en cuenta los registros adicionales que se insertarán (conocido como factor de llenado), que en sí mismo provoca problemas de rendimiento porque los datos están distribuidos en más páginas y por lo tanto más IO es necesario para acceder a toda la mesa.
Otros consejos
delego en la sabiduría de Kimberly L. Tripp sobre este tema:
Sin embargo, un GUID que no es secuencial - como uno que tiene sus valores generada en el cliente (utilizando .NET) O generadas por el newid función () (En SQL Server) puede ser una mala horrible elección - principalmente debido a la fragmentación que se crea en el tabla de base, sino también debido a su Talla. Es innecesariamente amplia (que es 4 veces más ancha que una identidad basada en la int - que le puede dar 2 mil millones (en realidad, 4 mil millones) filas únicas). Y, si necesita más de 2 mil millones se siempre se puede ir con un BIGINT (8 bytes int) y obtener 263-1 filas.
Para visualizar la imagen completa util llamado OSTRESS podría ser utilizado. P.ej. puede crear dos tablas: una con Normal GUID como PK, otro con GUID secuencial:
-- normal one
CREATE TABLE dbo.YourTable(
[id] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_YourTable] PRIMARY KEY NONCLUSTERED (id)
);
-- sequential one
CREATE TABLE dbo.YourTableSeq(
[id] [uniqueidentifier] NOT NULL CONSTRAINT [df_yourtable_id] DEFAULT (newsequentialid()),
CONSTRAINT [PK_YourTableSeq] PRIMARY KEY NONCLUSTERED (id)
);
A continuación, con un determinado util ejecuta un numbero de insertos con una selección de estadísticas sobre la fragmentación del índice:
ostress -Slocalhost -E -dYourDB -Q"INSERT INTO dbo.YourTable VALUES (NEWID()); SELECT count(*) AS Cnt FROM dbo.YourTable; SELECT AVG_FRAGMENTATION_IN_PERCENT AS AvgPageFragmentation, PAGE_COUNT AS PageCounts FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, N'LIMITED') DPS INNER JOIN sysindexes SI ON DPS.OBJECT_ID = SI.ID AND DPS.INDEX_ID = SI.INDID WHERE SI.NAME = 'PK_YourTable';" -oE:\incoming\TMP\ -n1 -r10000
ostress -Slocalhost -E -dYourDB -Q"INSERT INTO dbo.YourTableSeq DEFAULT VALUES; SELECT count(*) AS Cnt FROM dbo.YourTableSeq; SELECT AVG_FRAGMENTATION_IN_PERCENT AS AvgPageFragmentation, PAGE_COUNT AS PageCounts FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, N'LIMITED') DPS INNER JOIN sysindexes SI ON DPS.OBJECT_ID = SI.ID AND DPS.INDEX_ID = SI.INDID WHERE SI.NAME = 'PK_YourTableSeq';" -oE:\incoming\TMP\ -n1 -r10000
A continuación, en el archivo E: \ incoming \ TMP \ query.out usted encontrará sus estadísticas. Mis resultados son los siguientes:
"Normal" GUID:
Records AvgPageFragmentation PageCounts
----------------------------------------------
1000 87.5 8
2000 93.75 16
3000 96.15384615384616 26
4000 96.875 32
5000 96.969696969696969 33
10000 98.571428571428584 70
Sequential GUID:
Records AvgPageFragmentation PageCounts
----------------------------------------------
1000 83.333333333333343 6
2000 63.636363636363633 11
3000 41.17647058823529 17
4000 31.818181818181817 22
5000 25.0 28
10000 12.727272727272727 55
Como se puede ver con GUID generado secuencialmente ser insertado, el índice es mucho menos fragmentado como la operación de inserción conduce a nuevas más raro asignación de página.