Quando é melhor criar ESTATÍSTICAS em vez de criar um Índice?

38

Encontrei muitas informações sobre o que STATISTICS são: como elas são mantidas, como podem ser criadas manual ou automaticamente a partir de consultas ou índices e assim por diante. Porém, não consegui encontrar nenhuma orientação ou informações sobre "melhores práticas" sobre quandopara criá-los: quais situações se beneficiam mais com um objeto STATISTICS criado manualmente do que com um índice. Eu vi estatísticas filtradas criadas manualmente, ajudando as consultas em tabelas particionadas (porque as estatísticas criadas para os índices cobrem toda a tabela e não são por partição - brillaint!), Mas certamente deve haver outros cenários que se beneficiariam de um objeto de estatística enquanto sem precisar dos detalhes de um índice, nem valer o custo de manter o índice ou aumentar as chances de bloqueios / bloqueios.

@JonathanFite, em um comentário, mencionou uma distinção entre índices e estatísticas:

Os índices ajudarão o SQL a encontrar os dados mais rapidamente, criando pesquisas classificadas de maneira diferente da própria tabela. As estatísticas ajudam o SQL a determinar quanta memória / esforço será necessário para satisfazer a consulta.

Essa é uma ótima informação, principalmente porque me ajuda a esclarecer minha pergunta:

Como esse conhecimento (ou qualquer outra informação técnica sobre o que é e como s relacionadas com os comportamentos e natureza STATISTICS) ajudam a determinar quando para escolher CREATE STATISTICSao longo CREATE INDEX, especialmente quando a criação de um índice irá criar o relacionado STATISTICSobjeto? Qual cenário seria melhor atendido com apenas as informações ESTATÍSTICAS e sem o Índice?

Seria super útil, se possível, ter um exemplo prático de um cenário em que o STATISTICSobjeto se encaixa melhor que um INDEX.


Como sou um aprendiz / pensador visual, achei que poderia ajudar a ver as diferenças entre STATISTICSe INDEXes, lado a lado, como um possível meio de ajudar a determinar quando STATISTICSé a melhor escolha.

Thingy           PROs                             CONs
-------          ----------                       -------------------
INDEX            * Can help sorts.                * Takes up space.
                 * Contains data (can             * Needs to be maintained (extra I/O).
                   "cover" a query).              * More chances for blocking / dead-locks.

STATISTICS       * Takes up very little space.    * Cannot help sorts.
                 * Lighter maintenance / won't    * Cannot "cover" queries.
                   slow down DML operations.
                 * Does not increase chances
                   of blocking / dead-locks.

A seguir, alguns recursos que eu encontrei ao procurar isso, um que até faz a mesma pergunta, mas não foi respondido:

Índice do SQL Server vs estatística

Perguntas sobre estatísticas do SQL Server Estávamos com vergonha de perguntar

Estatisticas. Os histogramas de várias colunas são possíveis?

** Para ser claro, eu não tenho uma resposta para isso e, na verdade, estou procurando obter feedback de algumas pessoas, para fornecer o que parece estar estranhamente faltando informações aqui nas interwebs.

Solomon Rutzky
fonte
1
Os índices ajudarão o SQL a encontrar os dados mais rapidamente, criando pesquisas classificadas de maneira diferente da própria tabela. As estatísticas ajudam o SQL a determinar quanta memória / esforço será necessário para satisfazer a consulta.
Jonathan Fite
@JonathanFite Obrigado por esse comentário. Eu o incorporei na minha pergunta :).
Solomon Rutzky
Após o comentário de JonathanFite, parece que as estatísticas são melhores para aumentar o desempenho em sistemas ad hoc / tabelas / padrões de consulta, enquanto os índices são melhores para padrões de consulta previsíveis. Quero dizer isso como mais uma pergunta do que uma afirmação.
Dave

Respostas:

19

Sua pergunta gira em torno - Quando é bom apenas criar estatísticas versus criar índice (que cria estatísticas).

Nas minhas anotações internas do sql server (SQLSkills class- IE1 e IE2) e no livro interno do SQL Server , abaixo está meu entendimento limitado :

As estatísticas do SQL Server nada mais são do que objetos do sistema que contêm informações vitais sobre os valores da chave de índice e os valores regulares da coluna.

O SQL Server usa um modelo baseado em custo para escolher um plano de execução "suficientemente bom" o mais rápido possível. A estimativa de cardanilidade (estimativa do número de linhas a serem processadas em cada etapa da execução da consulta) é o fator mais importante na otimização de consultas, que afeta a estratégia de junção, o requisito de concessão de memória, a seleção de encadeamento de trabalho e a escolha de índices ao acessar dados .

O SQL Server não usará índices não clusterizados quando estima que um grande não. de operações de loop KEY ou RID serão necessárias, portanto, ele mantém estatísticas sobre índices (e colunas) que ajudarão nessas estimativas.

Há duas coisas importantes sobre as estatísticas:

  1. O histograma armazena informações sobre a distribuição de dados SOMENTE para a coluna de estatísticas mais à esquerda (índice). Ele também armazena informações sobre a densidade de várias colunas dos valores-chave. Portanto, essencialmente, o histograma armazena a distribuição de dados apenas para a coluna de estatísticas mais à esquerda.

  2. O SQL Server manterá no máximo 200 etapas no histograma, independentemente do tamanho da tabela. Os intervalos cobertos por cada etapa do histograma aumentam à medida que a tabela cresce, o que leva a estatísticas "menos precisas" para tabelas grandes.

    Lembre-se de que a seletividade do índice é uma métrica inversamente proporcional à densidade, ou seja, quanto mais valores únicos uma coluna tiver, maior será sua seletividade.

Quando consultas específicas não são executadas com muita frequência, você pode optar por criar estatísticas no nível da coluna em vez de um índice. As estatísticas no nível da coluna ajudam o Query Optimizer a encontrar melhores planos de execução, mesmo que esses planos sejam abaixo do ideal devido às verificações de índice envolvidas. Ao mesmo tempo, as estatísticas não adicionam uma sobrecarga durante as operações de modificação de dados e ajudam a evitar a manutenção do índice. Essa abordagem funciona apenas para consultas raramente executadas.

Referir :

Nota: Alguém como Paul White ou Aaron Bertrand pode entrar em cena para dar mais cor à sua boa pergunta .

Kin Shah
fonte
"O SQL Server não usará índices não clusterizados quando estima que será necessário um grande número de operações de loop KEY ou RID". Então, o QO pode usar o objeto de estatísticas com base em um índice independentemente do índice? Ou seja, se o índice não for ideal, mas a coluna principal estiver na consulta, as estatísticas ainda serão relevantes. Então eles seriam usados? Ou essas informações sugerem que pode haver casos em que um índice provavelmente não seria usado, mas como as estatísticas ainda têm valor, não há motivo real para criar o índice, basta fazer as estatísticas?
Solomon Rutzky
8

Eu diria que você precisa de um índice quando precisar limitar a quantidade de dados / obter os dados corretos rapidamente com base no (s) campo (s).

Você precisa de estatísticas quando precisa do otimizador para entender a natureza dos dados para poder executar as operações da melhor maneira possível.

O que eu descobri, as estatísticas filtradas ajudam quando você tem distorções nos seus dados que afetam fortemente o plano; por exemplo, no estouro de pilha, poucos usuários têm um grande número de postagens; portanto, usar apenas postagens médias por usuário não é realmente a melhor estimativa. Portanto, você pode criar uma estatística filtrada no userId com base no nome do usuário e, em seguida, o SQL Server deve saber que, quando esse nome de usuário está na consulta, esse é o ID do usuário que ele receberá e deve ser capaz de descobrir que o O campo indexado na tabela de postagens terá uma quantidade enorme de linhas com esse ID porque o histograma existe lá. Com as médias, não é possível fazer isso.

James Z
fonte
1
Olá, e obrigado por responder. Então, quando eu precisaria / desejaria que o otimizador entendesse melhor a natureza dos dados e ainda assim não estaria limitando esses dados ou desejando acessá-los mais rapidamente ou precisando "cobrir" a consulta? O mesmo para o seu exemplo de índice filtrado. Entendo o que você está dizendo em termos de separar casos extremos das médias, mas por que as estatísticas filtradas seriam melhores que um índice filtrado nos mesmos campos? Esta é a distinção que estou tentando chegar.
Solomon Rutzky
Como no exemplo, você não pode criar um índice filtrado no nome de usuário na tabela de postagens porque ele não existe lá. Você pode criá-lo com base no ID do usuário, mas isso não está na cláusula where.
James Z
Mas não UserIDestaria na condição JOIN, mesmo que não estivesse na WHERE? E isso não seria bom o suficiente para pegar um índice filtrado?
Solomon Rutzky
@srutzky Talvez seja mais provável nas versões mais atuais, mas em geral eu não confiaria nisso ... na maioria dos casos, os predicados precisam corresponder exatamente. Eu esqueço se eles corrigiram isso, mas em um ponto um índice filtrado WHERE BitColumn = 0não seria selecionado para uma consulta simples WHERE BitColumn <> 1. (E, para ser claro, a coluna de bits não era anulável.) Acho que houve casos semelhantes, como IntColumn > 10não corresponder IntColumn >= 11.
Aaron Bertrand
Os índices filtrados não podem ser usados ​​se houver uma chance de que da próxima vez que alguém use os planos, o índice filtrado não seja mais adequado. Não consigo pensar em nenhuma associação que possa usar um índice filtrado. Mesmo variáveis ​​não podem ser usadas, porque da próxima vez o valor poderá ser algo inadequado.
James Z
4

De 70-461 Livro de treinamento de Itzik Ben-Gan

Existem apenas alguns motivos possíveis para criar estatísticas manualmente. Um exemplo é quando um predicado de consulta contém várias colunas que têm relacionamentos entre colunas; as estatísticas nas várias colunas podem ajudar a melhorar o plano de consulta. As estatísticas em várias colunas contêm densidades entre colunas que não estão disponíveis nas estatísticas de coluna única. No entanto, se as colunas já estiverem no mesmo índice, o objeto de estatísticas de várias colunas já existe, portanto, você não deve criar um adicional manualmente.

Kentaro
fonte
Obrigado por postar isso. Isso responde parte da minha pergunta, mas ainda deixa em aberto a questão de: Se eu precisar das estatísticas de várias colunas, por que eu criaria apenas STATISTICS em vez do Index, que incluiria STATISTICS mais informações adicionais que poderiam ajudar ainda mais a consulta ( s)?
Solomon Rutzky
1
Acho que a explicação de Kin explicaria melhor o que você procura. Talvez um monte que seja frequentemente inserido, mas raramente consultado?
Kentaro 23/10