Eu tenho um banco de dados do SQL Server em que as consultas são muito lentas e há muitos bloqueios e bloqueios.
Quando olho para os DMVs de índice ausentes e os planos de consulta, não há sugestões.
Por que é que?
fonte
Eu tenho um banco de dados do SQL Server em que as consultas são muito lentas e há muitos bloqueios e bloqueios.
Quando olho para os DMVs de índice ausentes e os planos de consulta, não há sugestões.
Por que é que?
Examinaremos alguns dos motivos com mais detalhes e também falaremos sobre algumas das limitações gerais do recurso.
Primeiro, de: Limitações do recurso de índices ausentes :
- Ele não especifica uma ordem para as colunas serem usadas em um índice.
Conforme observado nestas perguntas e respostas: Como o SQL Server determina a ordem das colunas principais nas solicitações de índice ausentes? , a ordem das colunas na definição de índice é ditada pelo predicado Igualdade vs Desigualdade e depois pela posição ordinal da coluna na tabela.
Não há suposições sobre a seletividade e pode haver uma ordem melhor disponível. É seu trabalho descobrir isso.
Índices Especiais
As solicitações de índice ausentes também não cobrem índices 'especiais', como:
As colunas-chave do Índice ausente são geradas a partir de colunas usadas para filtrar resultados, como aqueles em:
As colunas incluídas no índice ausente são geradas a partir de colunas exigidas pela consulta, como as de:
Mesmo que com bastante frequência, as colunas pelas quais você está ordenando ou agrupando podem ser benéficas como colunas-chave. Isso remonta a uma das limitações:
- Não se destina a ajustar uma configuração de indexação.
Por exemplo, esta consulta não registrará uma solicitação de índice ausente, mesmo que a adição de um índice em LastAccessDate impeça a necessidade de Classificar (e espalhar para o disco).
SELECT TOP (1000) u.DisplayName
FROM dbo.Users AS u
ORDER BY u.LastAccessDate DESC;
Este agrupamento também não consulta no local.
SELECT TOP (20000) u.Location
FROM dbo.Users AS u
GROUP BY u.Location
Bem, sim, mas é melhor que nada. Pense na falta de pedidos de índice como um bebê chorando. Você sabe que há um problema, mas depende de você, como adulto, descobrir qual é esse problema.
Relaxe, bucko. Estamos chegando lá.
Se você ativar o TF 2330 , as solicitações de índice ausentes não serão registradas. Para descobrir se você tem isso ativado, execute o seguinte:
DBCC TRACESTATUS;
A reconstrução de índices limpará as solicitações de índice ausentes. Portanto, antes de começar o Hi-Ho-Silver-Away, reconstruindo todos os índices no segundo em que um pingo de fragmentação se infiltra, pense nas informações que você está limpando toda vez que faz isso.
Você também pode pensar em Por que desfragmentar seus índices não está ajudando , de qualquer maneira. A menos que você esteja usando o Columnstore .
Adicionar, remover ou desativar um índice limpará todas as solicitações de índice ausentes para essa tabela. Se você estiver trabalhando com várias alterações de índice na mesma tabela, certifique-se de escrevê-las todas antes de fazer alguma.
Se um plano for simples o suficiente, e a opção de acesso ao índice for óbvia o suficiente, e o custo for baixo o suficiente, você obterá um plano trivial.
Isso significa efetivamente que não houve decisões baseadas em custos para o otimizador tomar.
Via Paul White :
Os detalhes de quais tipos de consulta podem se beneficiar do Trivial Plan mudam com frequência, mas coisas como junções, subconsultas e predicados de desigualdade geralmente impedem essa otimização.
Quando um plano é trivial, as fases adicionais de otimização não são exploradas e os índices ausentes não são solicitados .
Veja a diferença entre essas consultas e seus planos :
SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2;
SELECT *
FROM dbo.Users AS u
WHERE u.Reputation = 2
AND 1 = (SELECT 1);
O primeiro plano é trivial e nenhuma solicitação é mostrada. Pode haver casos em que os erros impedem a exibição de índices ausentes nos planos de consulta; eles geralmente são registrados com mais confiabilidade nas DMVs de índice ausentes.
Predicados em que o otimizador não seria capaz de usar um índice com eficiência, mesmo com um índice, podem impedir que eles sejam registrados.
Coisas que geralmente não são SARGable são:
SELECT *
FROM dbo.Users AS u
WHERE ISNULL(u.Age, 1000) > 1000;
SELECT *
FROM dbo.Users AS u
WHERE DATEDIFF(DAY, u.CreationDate, u.LastAccessDate) > 5000
SELECT *
FROM dbo.Users AS u
WHERE u.UpVotes + u.DownVotes > 10000000
DECLARE @ThisWillHappenWithStoredProcedureParametersToo NVARCHAR(40) = N'Eggs McLaren'
SELECT *
FROM dbo.Users AS u
WHERE u.DisplayName LIKE @ThisWillHappenWithStoredProcedureParametersToo
OR @ThisWillHappenWithStoredProcedureParametersToo IS NULL;
Nenhuma dessas consultas registrará solicitações de índice ausentes. Para mais informações, consulte os seguintes links:
Veja este índice:
CREATE INDEX ix_whatever ON dbo.Posts(CreationDate, Score) INCLUDE(OwnerUserId);
Parece bom para esta consulta:
SELECT p.OwnerUserId, p.Score
FROM dbo.Posts AS p
WHERE p.CreationDate >= '20070101'
AND p.CreationDate < '20181231'
AND p.Score >= 25000
AND 1 = (SELECT 1)
ORDER BY p.Score DESC;
O plano é uma busca simples ...
Mas como a coluna principal é para o predicado menos seletivo, acabamos fazendo mais trabalho do que deveríamos:
Tabela 'Posts'. Contagem de escaneamentos 13, leituras lógicas 136890
Se alterarmos a ordem da coluna da chave de índice, faremos muito menos trabalho:
CREATE INDEX ix_whatever ON dbo.Posts(Score, CreationDate) INCLUDE(OwnerUserId);
E significativamente menos leituras:
Tabela 'Posts'. Contagem de digitalizações 1, leituras lógicas 5
Em certos casos, o SQL Server optará por criar um índice em tempo real por meio de um spool de índice. Quando um spool de índice está presente, uma solicitação de índice ausente não será. Certamente, adicionar o índice você mesmo pode ser uma boa ideia, mas não conte com o SQL Server para ajudá-lo a descobrir isso.