Eu estava lendo Clustered
e Non Clustered Indexes
.
Clustered Index
- Ele contém páginas de dados. Isso significa que as informações completas da linha estarão presentes na coluna Índice agrupado.
Non Clustered Index
- Ele contém apenas as informações do Localizador de linhas na forma de coluna Índice clusterizado (se disponível) ou o Identificador de arquivo + Número da página + Linhas totais em uma página. Isso significa que o mecanismo de consulta deve executar uma etapa adicional para localizar os dados reais.
Consulta - Como posso verificar a diferença de desempenho com a ajuda de um exemplo prático, pois sabemos que a tabela pode ter apenas um Clustered Index
e fornece sorting
no Clustered Index Column
e Non Clustered Index
não fornece sorting
e pode suportar 999 Non Clustered Indexes
pol SQL Server 2008
e 249 pol SQL Server 2005
.
Respostas:
Muito boa pergunta, pois é um conceito tão importante. Este é um tópico importante e o que vou mostrar é uma simplificação para que você possa entender os conceitos básicos.
Em primeiro lugar, quando você vê a tabela de índice de cluster . No SQL server, se uma tabela não contém um índice em cluster, é uma pilha. Criar um índice em cluster na tabela na verdade transforma a tabela em uma estrutura do tipo b-tree. Seu índice clusterizado É sua tabela, não está separado da tabela
Você já se perguntou por que você pode ter apenas um índice em cluster? Bem, se tivéssemos dois índices agrupados, precisaríamos de duas cópias da tabela. Afinal, ele contém os dados.
Vou tentar explicar isso usando um exemplo simples.
NOTA: Criei a tabela neste exemplo e a preenchi com mais de 3 milhões de entradas aleatórias. Em seguida, executou as consultas reais e colou os planos de execução aqui.
O que você realmente precisa entender é notação O ou eficiência operacional . Vamos supor que você tenha a tabela a seguir.
Portanto, aqui temos uma tabela básica com uma chave agrupada no Código do Cliente (a chave primária é agrupada por padrão). Assim, a tabela é organizada / ordenada com base na chave primária CustomerID. Os níveis intermediários conterão os valores CustomerID. As páginas de dados conterão a linha inteira, portanto, é a linha da tabela.
Também criaremos um índice não agrupado no campo CustomerName. O código a seguir fará isso.
Portanto, neste índice, você encontrará nas páginas de dados / nós no nível da folha um ponteiro para os níveis intermediários no índice em cluster. O índice é organizado / ordenado em torno do campo CustomerName. Portanto, o nível intermediário contém os valores CustomerName e o nível da folha conterá o ponteiro (esses valores de ponteiro são, na verdade, os valores da chave primária ou a coluna CustomerID).
Certo, se executarmos a seguinte consulta:
O SQL provavelmente lerá o índice em cluster por meio de uma operação de busca. Uma operação de busca é uma pesquisa binária que é muito mais eficiente do que uma varredura que é uma pesquisa seqüencial. Portanto, no exemplo acima, o índice é lido e, usando uma pesquisa binária, o SQL pode eliminar os dados que não correspondem aos critérios que estamos procurando. Veja a captura de tela anexada para o plano de consulta.
Portanto, o número de operações ou Notação O para a operação de busca é o seguinte:
Então são duas operações. No entanto, se executarmos a seguinte consulta:
O SQL agora usará o índice não clusterizado no CustomerName para fazer a pesquisa. No entanto, como esse é um índice sem cluster, ele não contém todos os dados na linha.
Portanto, o SQL fará a pesquisa nos níveis intermediários para encontrar os registros correspondentes e faça uma pesquisa usando os valores retornados para fazer outra pesquisa no índice clusterizado (também conhecido como tabela) para recuperar os dados reais. Isso parece confuso, eu sei, mas continue a ler e tudo ficará claro.
Como nosso índice não agrupado em cluster contém apenas o campo CustomerName (os valores do campo indexado armazenados nos nós intermediários) e o ponteiro para os dados que são o CustomerID, o índice não possui registro do CustomerSurname. O CustomerSurname deve ser buscado no índice ou tabela em cluster.
Ao executar esta consulta, recebo o seguinte plano de execução:
Há duas coisas importantes para você notar na captura de tela acima
Por que o SQL está sugerindo o índice no CustomerName novamente? Bem, já que o índice contém apenas o CustomerID e o CustomerName SQL ainda precisa encontrar o CustomerSurname na tabela / índices agrupados.
Se criamos o índice e incluímos a coluna CustomerSurname no índice, o SQL poderá satisfazer a consulta inteira apenas lendo o índice não agrupado em cluster. É por isso que o SQL está sugerindo que eu mude meu índice não agrupado em cluster.
Aqui você pode ver a operação extra que o SQL precisa fazer para obter a coluna CustomerSurname da chave em cluster
Assim, o número de operações é o seguinte:
São 4 operações para obter os valores. O dobro da quantidade de operações necessárias em comparação com a leitura do índice em cluster. O programa mostra que seu índice clusterizado é o índice mais poderoso, pois contém todos os dados.
Então, apenas para esclarecer um último ponto. Por que digo que o ponteiro no índice não agrupado é o valor da chave primária? Bem, para demonstrar que os nós no nível folha do índice não clusterizado contêm o valor da chave primária, altero minha consulta para:
Nesta consulta, o SQL pode ler o Código do Cliente no índice não clusterizado. Não é necessário fazer uma pesquisa no índice clusterizado. Isso você pode ver pelo plano de execução que se parece com isso.
Observe a diferença entre esta consulta e a consulta anterior. Não há pesquisa. SQL pode encontrar todos os dados no índice não agrupado em cluster
Esperamos que você possa começar a entender que o índice clusterizado é a tabela e os índices não clusterizados NÃO contêm todos os dados. A indexação acelerará as seleções devido ao fato de que pesquisas binárias podem ser feitas, mas apenas índices agrupados contêm todos os dados. Portanto, uma pesquisa em um índice não clusterizado quase sempre resultará no carregamento de valores do índice clusterizado. Essas operações extras tornam os índices não agrupados em cluster menos eficientes que um índice agrupado.
Espero que isso esclareça as coisas. Se algo não fizer sentido, poste um comentário e tentarei esclarecer. É bastante tarde aqui e meu cérebro está um pouco tenso. Hora de um touro vermelho.
fonte
"Isso significa que o mecanismo de consulta deve executar uma etapa adicional para localizar os dados reais."
Não necessariamente - se o índice estiver cobrindo uma determinada consulta, nenhuma viagem deverá ser feita nas páginas de dados. Além disso, com as colunas incluídas, colunas adicionais podem ser adicionadas a um índice não agrupado para torná-lo coberto sem alterar o tamanho da chave.
Portanto, a resposta final é - Depende (de muito mais informações do que você realmente pode cobrir em uma única pergunta) - você precisa entender todos os recursos dos índices e o plano de execução de uma determinada consulta pode divergir das suas expectativas.
Uma regra geral prática que tenho é que uma tabela sempre possui um índice em cluster (e geralmente em uma identidade ou GUID seqüencial), mas os índices não em cluster são adicionados para desempenho. Mas sempre há exceções - as tabelas de heap têm um lugar, índices clusterizados mais amplos têm um lugar. Os índices aparentemente redundantes, mais estreitos para caber em mais linhas por página, têm um lugar. etc etc.
E eu não me preocuparia com os limites dos vários índices permitidos - isso quase certamente não entrará em jogo em muitos exemplos do mundo real.
fonte
there are always exceptions
- muitas pessoas omitem isso e pensam que todo índice agrupado deve ser umint identity
que seja.