DBCC PAGE
Continuando a série dos comandos históricos, vamos falar sobre o famoso DBCC PAGE. Esse é o quarto artigo da série: já comentei sobre o SET STATISTICS IO, DBCC DROPCLEANBUFFERS e DBCC SHOWCONTIG.
Vou recriar o ambiente do LOJADB:
Em seguida, quero me certificar que está funcionando tudo corretamente.
Antes de continuar, algumas pessoas desconfiaram da forma como construi a tabela. Estou usando o tipo de dados CHAR(800) ao invés do tradicional VARCHAR. Por isso, vou mudar o tipo de coluna. Por ser um tipo variável, vou trocar para VARCHAR(1000).
A tabela foi alterada para a nova coluna VARCHAR.
Rodei o sp_spaceused antes de começar os testes para validar a quantidade de registro e o tamanho da tabela. Curiosamente, não lembro da tabela ocupar 20MB, parece que está maior.
Vamos fazer o teste de desempenho. Começarei limpando o cache e depois habilitando o SET STATISTICS TIME e SET STATISTICS IO.
Apenas para manter a consistência dos testes, vou desabilitar o read-head usando o Trace Flag global 652. Limpando o cache e executando novamente:
Consegui bater o recorde do tempo! Agora a query está rodando em 2659ms.
Investigação usando o DBCC PAGE
Por algum motivo houve um aumento significativo no número de logical reads (7502), assim como nas leituras físicas (2506). Por isso, comecei olhando as páginas em memória do Buffer Pool. Encontrei exatamente 2509 páginas pertencentes ao LOJADB. No entanto, o que me chamou a atenção foi existir páginas com 8 registros e outras, com apenas 4.
A investigação continua com a ajuda do DBCC PAGE.
Esse comando está disponível desde os primórdios do SQL Server e deve ser usado em conjunto com o Trace Flag 3604.
DBCC PAGE (SQL 6.5)
https://support.microsoft.com/en-us/kb/83065
A sintaxe é simples:
DBCC PAGE(dbid, file_id, page_id, opt)
Vamos investigar a página 26057, que possui 4 registros.
Cabeçalho:
A resposta está no tipo de registro armazenado! Esses 4 registros são FORWARDED_RECORD.
Rodando o DBCC PAGE nas páginas com 8 registros, encontro os ponteiros FORWARDING_STUB:
O mistério está resolvido. Ao executar o comando ALTER TABLE - ALTER COLUMN, os registros foram “expulsos” da página para uma página externa usando os mecanismos de “forwarded records”.
Existe uma boa explicação disso no livro “Inside SQL Server”. Também encontrei esse artigo do Paul Randal:
Inside the Storage Engine: Anatomy of a record
https://www.sqlskills.com/blogs/paul/inside-the-storage-engine-anatomy-of-a-record/
Conclusão
Ao mudar o tipo de dado da coluna, forçamos a ocorrência de Forwarded Records e causamos a fragmentação de dados em disco. Esse problema ocorreu porque a tabela está organizado como Heap e não estamos trabalhando com Clustered Index.
No próximo artigo, vou mostrar um comportamento muito curioso das Heaps. Ainda preciso pensar no título.
Comments
- Anonymous
April 22, 2016
Fabricio, excelente série de artigos! Parabéns! Poderia postar o link do livro "Inside SQL Server"?- Anonymous
April 26, 2016
Oi Rodrigo, obrigado pelo comentário. Eu comentei do Inside SQL Server 2000 (http://www.amazon.com/Inside-Microsoft-SQL-Server-2000/dp/0735609985), embora provavelmente as outras versões do livro também falem sobre o DBCC PAGE.
- Anonymous