SQL Server — Cuidado com os índices II
Nos últimos 8 anos de minha vida trabalhei muito com SQL SERVER (MSSQL) de forma que a gente acaba criando uma certa habilidade implícita.
Reparei em meu trabalho que a preocupação de alguns desenvolvedores a achar uma solução para desempenho de banco de dados esta condicionada aos índices, claro que quando todas as boas práticas estão firmadas nas operações no banco de dados. Ao me reparar com este pequeno problema, andei pesquisando sobre se criar um índice iria agradar o desempenho do sistema.
Antes de mostrar o fato real, vou comentar um pouco sobre pilha, índices clusterizados e não clusterizados.
Pilha ou Heap
Quando criamos uma tabela no banco de dados do SQL é inserido um registro na página de dados sem nenhum cuidado, somente na ordem que foi colocado. Neste caso acima, vamos pensar que esta tabela não tem uma PK (caso difícil), mas por um bom fator que explico logo abaixo. Voltando a inserção (sem pk na table), as páginas que recebem esses registros não são do tipo indexadas, são do tipo pilha…. isso mesmo, vai entrando e vai entrando dados até encher o topo. Há desculpe-me, podem ser chamadas também de heaps.
E qual o problema da página da tabela ser do tipo heap? Bem meu amigo, acho que você já deve ter ouvido falar de table scan, se não ouviu.. imagine pelo nome… cada consulta é um scan dentro da tabela procurando pelo dado pesquisado. Imagine ai, isso em um sistema com vários acesso simultâneos. A performance do banco de dados vai topar.. e isso vai deixar o DBA doidooo, pelo menos o do meu trabalho pira! (E vc precisa conhecer ele, um cara top!!)
Índices Não-Clusterizados e Clusterizados.
Ai que entra os índices clusterizados e não-clusterizados.
Vamos começar pelos não-clusterizados. São praticamente um catálogo que relaciona os valores de um ou mais campos da tabela com aquela página de dados que estávamos falando agora acima. Assim, cada pesquisa/consulta feita, o otimizador de consultas vai retornar de forma bem mais rápida qual a página de dados a ser lida, resultando no dados de forma mais eficaz. E isso, foi algo muito bom.
E então? Se foi bom, qual a diferença dele p/ o clusterizado?
É, foi bom.. mais teve algo bem melhor que foi a criação do índice clusterizado. Tão bom quanto que a própria MICROSOFT colocou por default, que o campo PK da tabela seria automaticamente um índice clusterizado. (Lembra que eu disse q ia falar sobre o PK?)
Vale lembrar galera, que eles tem uma estrutura B-TREE. Não lembra o que é isso? Te lembro logo abaixo.

Então beleza!! Vamos continuar.. O índice clusterizado por sua vez trabalha registrando nas páginas de dados já de forma ordenada com base em um ou mais campos da planilha, sendo assim, as próprias páginas de dados da tabela funcionariam como um índice. Como mostrei na figura acima, eles trabalham na estrutura B-TREE, só que neste caso o nível mais detalhado (no exemplo acima o Leaf Level ou Folhas) é composta pelas próprias páginas de dados da tabela, ordenadas conforme a definição do índice. Em resumo, quando existe um índice clusterizado, todos os outros demais índices da tabela se aproveitam da ordenação destas páginas melhorando a eficiência.
Bem, isso foi um resumo do resumo sobre índices não clusterizados e clusterizados. Claro que existem outros índices no SQL SERVER como por exemplo: índices espaciais, xml e etc.. Mas o título desta publicação não tem propósito até a aqui.
Antes, gostaria de informar uma coisa que esqueci. Cada página do SQL server tem o tamanho de 8KB (se você não viu minha publicação anterior, clique aqui) significando que cada banco de dados têm 128 páginas por megabyte, cada página começa com um cabeçalho de de 96 bytes que armazena informações de sistema sobre a página. Visualize a imagem abaixo:

Incluindo Registros no Banco de Dados
Na publicação passado, falei sobre a quantidade de bytes que cada linha inserida em uma tabela vai consumir. Quando inserimos um dado na tabela(considerando que esta tabela tem uma PK, então indice clustered), o SQL vai procurar a próxima página ativa e verificar se tem espaço suficiente para inserir este dado. Se o registro do novo dado não couber na página, o SQL por sua vez, vai quebrar a página atual em duas para manter a ordenação, ocorrendo o page split.
Page Split
O que seria o page split? O próprio nome já diz, mas para ser mais exato acontece o seguinte: O SQL praticamente pega a próxima página vazia na extensão e manda metade dos dados da página que ele queria inserir o dado, depois disso o registro é inserido nesta página. Se não houver página vazia na extensão, ele invoca uma nova extensão que esteja vazia.. e se por fimm não tiver nenhuma próxima extensão.. ai o bixo pega.. ai acontece um AutoGrowth. O que seria o AutoGrowth? Em resumo , o SQL vai alocar novas porções do disco e vai separá-las em segmentos de 64kb (8 páginas de 8kb).
Estas ações consomem desempenho de forma enorme, além de termos duas páginas com 50% de espaço inutilizado. Em Resumo, isso é prejudicial ao banco de dados.. pois consome tempo, processamento e desperdiça espaço.