DBCC INDEXDEFRAG

Esse é mais um artigo da série “Saga da otimização com comandos antigos”

No último artigo, falei sobre a forma mais rápida de executar um scan. Nesse artigo vou falar sobre o INDEX SCAN.

Seria ele mais rápido que o HEAP SCAN do artigo anterior?

Vamos começar colocando ordem na heap!

Heap é Desorganizada

Heap scan é uma técnica muito rápida porque favorece o uso das operações de read-ahead.

Entretanto, imagine o que acontece quando sabemos que a query retorna apenas um registro:

SELECT * FROM produtos WHERE id = 1234

Isso poderia ser reescrito assim:

SELECT TOP(1) * FROM produtos WHERE id = 1234

A primeira query realiza a leitura da tabela inteira para retornar todos os produtos com ID = 1234 e o comando faz a leitura de todos os registros para se certificar que, de fato, existe apenas um registro. Por outro lado, a segunda query usa TOP(1) para notificar que é necessário apenas um registro. Assim, o comando realiza o scan de tabela e finaliza logo que encontrar o primeiro registro. Estatisticamente, podemos dizer que a segunda query executa na metade do tempo da primeira.

Concluímos que a heap é um conjunto desorganizado de página de dados, ou seja, a única forma de acesso é através do Heap Scan. Uma das formas de tornar o acesso mais rápido é usando o TOP(n) para encerrar o scan o mais rápido possível.

Heap Organizada

Existe uma forma de tornar a Heap mais eficiente: ordenando os registros nas páginas de dados.

Heap: dados desorganizados – será que existe o ID = 1234? onde?

image

Heap Organizada: é fácil de encontrar o ID = 1234.

image

Tornar a heap organizada é fácil! Basta transformar a Heap em uma Tabela com Clustered Index.

Clustered Index

Clustered Index. Sim, esse é o nome de uma Heap Organizada.

Infelizmente não gosto desse nome porque muita gente considera o Clustered Index mais como índice ao invés de Tabela. Índice é uma estrutura para ajudar o desempenho do banco de dados e você pode criar vários na mesma tabela (10, 20, 30..). Entretanto, o Clustered Index é especial e você só pode criar um porque ele é a própria tabela! Não há como organizar a Heap de duas formas diferentes ao mesmo tempo.

Clustered index organiza as páginas da tabela. A forma mais fácil de enxergar isso é através do comando DBCC IND. Vamos investigar o index_id = 1, que corresponde ao índice clustered.

image

A página 1:549 aponta para a próxima página next_id = 1:548 e anterior prev_id = 1:550. Podemos investigar a página anterior 1:550, que aponta para as páginas 1:549 e 1:551. Aqui é possível ver que a primeira página da tabela é a 1:557, pois ela não possui um ponteiro para a página anterior.

 

Desorganizando o Clustered Index

Sempre que realizamos uma operação de Table Scan em uma tabela com índice clustered, dizemos que:

Table Scan = Clustered Index Scan

Em geral o desempenho do Clustered index scan é comparável com o Heap scan. O motivo é que as páginas estão organizadas e fica fácil de encontrar as informações. Entretanto, existe uma forma de bagunçar o local onde os dados estão fisicamente armazenados: basta fragmentar a tabela e começar a distribuir os dados em diferentes páginas.

Primeiro vamos criar uma tabela e adicionar a ordenação com índice clustered:

image

Em seguida, adicionamos os produtos sem uma ordem específica.

image

O resultado do DBCC IND mostra claramente que as páginas anteriores e posteriores estão completamente fora de ordem.

image

Como as páginas estão desordenadas, Clustered Index Scan não consegue executar transformar as operações de leitura em operações de read-ahead.

Isso torna o acesso ao índice mais lento. Como resolver? Basta desfragmentar o índice. No passado, usava-se bastante o comando DBCC INDEXDEFRAG. Hoje não há motivo para usar o INDEXDEFRAG, pois se tornou obsoleto. Ao invés disso, procure usar a sintaxe do ALTER INDEX REORGANIZE que possui mais flexibilidade e suporte a partições.

ALTER INDEX nome_indice ON produtos REORGANIZE

image

Pronto! Agora o clustered index scan é praticamente tão rápido quanto heap scan e deixa a tabela organizada.

Conclusão

É recomendado organizar os dados da tabela usando um índice clustered.

Nesse artigo comentei que o desempenho Clustered Index scan é igual ao Heap scan ou inferior (quando o índice se encontra fragmentado). Portanto, criar um índice clustered sem qualquer estudo pode causar degradação de performance.

Criar um clustered index incorreto é pior do que não te-lo.

No próximo artigo vamos explorar um pouco mais a estrutura do índice, também conhecida por BTree+.