Nosso projeto executa um banco de dados muito grande e muito complicado. Então, cerca de um mês atrás, percebemos que o espaço usado por colunas indexadas contendo valores nulos estava ficando muito grande. Como resposta a isso, escrevi como um script que pesquisaria dinamicamente todos os índices de coluna única contendo mais de 1% dos valores nulos, eliminando e recriando esses índices como índices filtrados, com a condição de que o valor NÃO fosse NULL. Isso descartaria e recriaria centenas de índices em todo o banco de dados e normalmente liberaria quase 15% do espaço usado por todo o banco de dados.
Agora eu tenho duas perguntas sobre isso:
A) Quais são as desvantagens do uso de índices filtrados dessa maneira? Eu diria que isso apenas melhoraria o desempenho, mas há algum risco de desempenho envolvido?
B) Recebemos erros ( 'não é possível descartar o índice XYZ porque ele não existe ou você não tem permissão' ) ao descartar e recriar os índices, mesmo que, depois de verificados, tudo tenha corrido exatamente como o esperado. Como isso pode acontecer?
Obrigado por qualquer ajuda!
Edit: Em resposta a @Thomas Kejser
Olá e obrigado, mas acontece que foi um desastre. Na época, não entendemos várias coisas, como:
- Durante uma consulta, o SQLOS faz planos de índice antes de determinar que não pode usar valores NULL para ingressar nas colunas da tabela. IE, você realmente precisa ter um filtro de cláusula WHERE que ajuste o índice para cada índice filtrado usado na consulta ou o índice não será usado.
- Descartar e criar índices e atualizar redundantemente suas estatísticas mais uma vez depois ainda pode não ser suficiente para produzir os planos atualizados, o que supusemos que eles faria. Em alguns casos, parece que apenas uma carga de trabalho alta o suficiente forçará o SQL Server a reavaliar os planos.
- Existem algumas características exóticas na funcionalidade do planejador de execução que são difíceis de determinar apenas pelo senso comum e pela lógica. Mesmo com milhares de variações geradas por código por trás de consultas diferentes, índices aparentemente inúteis podem ajudar em algumas estatísticas e planos de consulta que acabam sendo usados em consultas críticas.
No final, essas mudanças foram revertidas. Portanto, os índices filtrados são uma ferramenta poderosa, mas você precisa realmente entender exatamente quais dados estão sendo buscados nessas colunas. Onde os índices normais, além dos problemas de espaço, são bastante fáceis de aplicar, os índices filtrados representam soluções muito personalizadas. Eles certamente não substituem um índice regular, mas uma extensão para eles nas circunstâncias especiais em que são necessários.
Respostas:
Abordagem muito interessante. Meu voto positivo pela criatividade.
Desde que você recuperou o espaço, presumo que os índices originais não estejam mais no lugar? As desvantagens dos índices filtrados são:
Em termos práticos, isso significa que você precisa ser extremamente cuidadoso com os índices filtrados, pois eles geralmente resultam em planos de consulta horríveis. Eu não chegaria a chamá-los de inúteis, mas os vejo como uma adição aos índices tradicionais, não como um substituto (como você está tentando fazer).
fonte
Thomas Kejser responde a este tópico bem acima.
Eu apenas pensei em adicionar 2 centavos.
Vi alguns índices filtrados sendo usados apenas (mostrados no plano de execução) quando você corresponde exatamente à cláusula where na sua consulta como a where no índice filtrado.
você tentou usar visualizações indexadas ? colunas esparsas ?
Acredito que, desde que você tenha apenas juntas internas, é possível criar uma exibição indexada contendo a (s) cláusula (s) where de seus índices filtrados e, em seguida, você pode usá-la.
Pode haver mais de uma visualização. Mas, da mesma forma que nos índices não agrupados, muitos atrasarão sua anotação.
Na minha experiência, você teria bons ganhos em leitura, mas teria que monitorar gravações (inserções e atualizações), especialmente se as tabelas estiverem envolvidas na replicação.
No entanto, como eu entendo sua principal preocupação
the null values
, sugiro colunas SPARSE nos seus índices .Colunas esparsas são especialmente apropriadas para índices filtrados
Como anunciei colunas esparsas, não me sentiria bem se também não dissesse suas limitações:
Como resultado disso
Considere o exemplo de uma tabela que possui 600 colunas esparsas do tipo bigint.
mais detalhes no link acima, porém prefiro postar aqui também este aviso:
O Mecanismo de Banco de Dados do SQL Server usa o seguinte procedimento para realizar essa alteração:
1 - Adiciona uma nova coluna à tabela no novo tamanho e formato de armazenamento.
2 - Para cada linha da tabela, atualiza e copia o valor armazenado na coluna antiga para a nova coluna.
3 - Remove a coluna antiga do esquema da tabela.
4 - Reconstrói a tabela (se não houver índice em cluster) ou reconstrói o índice em cluster para recuperar o espaço usado pela coluna antiga.
fonte