Pergunta

Estou tentando entender como o guid sequencial tem melhor desempenho do que um guid normal.

É porque com o guid regular, o índice usa o último byte do guid para classificar?Por ser aleatório, causará muita fragmentação e divisões de páginas, pois muitas vezes moverá dados para outra página para inserir novos dados?

Guia senoidal sequencial é sequencial e causará muito menos divisões e fragmentação de páginas?

Meu entendimento está correto?

Se alguém puder esclarecer mais sobre o assunto, agradecerei muito.

Obrigado

EDITAR:

Guid sequencial = NEWSEQUENTIALID(),

Guia normal = NEWID()

Foi útil?

Solução

Você praticamente disse tudo em sua pergunta.

Com um GUID/chave primária sequencial, novas linhas serão adicionadas no final da tabela, o que torna as coisas fáceis para o SQL Server.Em comparação, uma chave primária aleatória significa que novos registros podem ser inseridos em qualquer lugar da tabela - a chance da última página da tabela estar no cache é bastante provável (se é para lá que todas as leituras estão indo), no entanto, a chance de uma página aleatória no meio da tabela no cache é bastante baixa, o que significa que é necessária E/S adicional.

Além disso, ao inserir linhas no meio da tabela existe a possibilidade de não haver espaço suficiente para inserir a linha extra.Se for esse o caso, o SQL Server precisará executar operações IO adicionais e caras para criar espaço para o registro - a única maneira de evitar isso é ter lacunas espalhadas entre os dados para permitir a inserção de registros extras (conhecido como um Fator de preenchimento), o que por si só causa problemas de desempenho porque os dados estão espalhados por mais páginas e, portanto, é necessário mais IO para acessar a tabela inteira.

Outras dicas

Defer à sabedoria de Kimberly L. Tripp sobre este tópico:

Mas, um guia que não é seqüencial - como um que possui seus valores gerados no cliente (usando .NET) ou gerado pela função newid () (no servidor SQL) pode ser uma escolha terrivelmente ruim - principalmente por causa da fragmentação que Ele cria na tabela base, mas também por causa de seu tamanho. É desnecessariamente largo (é 4 vezes mais largo que uma identidade baseada em INT - que pode oferecer 2 bilhões de linhas únicas (realmente, 4 bilhões)). E, se você precisar de mais de 2 bilhões, sempre poderá usar um Bigint (8 bytes Int) e obter 263-1 linhas.

Consulte Mais informação: http://www.sqlskills.com/blogs/kimberly/post/guids-as-primary-keys-andor-the-cluering-key.aspx#ixzz0wdk6cece

Para visualizar a imagem inteira Util nomeado Ostress pode ser usado. Por exemplo, você pode criar duas tabelas: uma com normal Guid como PK, outro com Guid sequencial:

-- 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)
);

Então, com um determinado Util, você executa várias inserções com a seleção de estatísticas sobre a fragmentação do í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

Então, no arquivo e: recebendo tmp query.out, você encontrará suas estatísticas. Meus resultados são:

"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 você pode ver com o GUID gerado sequencialmente sendo inserido, o índice é muito menos fragmentado à medida que a operação de inserção leva à nova alocação de página mais rara.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top