Eu tenho a seguinte consulta SQL:
SELECT
Event.ID,
Event.IATA,
Device.Name,
EventType.Description,
Event.Data1,
Event.Data2
Event.PLCTimeStamp,
Event.EventTypeID
FROM
Event
INNER JOIN EventType ON EventType.ID = Event.EventTypeID
INNER JOIN Device ON Device.ID = Event.DeviceID
WHERE
Event.EventTypeID IN (3, 30, 40, 41, 42, 46, 49, 50)
AND Event.PLCTimeStamp BETWEEN '2011-01-28' AND '2011-01-29'
AND Event.IATA LIKE '%0005836217%'
ORDER BY Event.ID;
Eu também tenho um índice na Event
tabela para a coluna TimeStamp
. Meu entendimento é que esse índice não é usado por causa da IN()
declaração. Portanto, minha pergunta é: existe uma maneira de criar um índice para essa IN()
instrução específica para acelerar essa consulta?
Também tentei adicionar Event.EventTypeID IN (2, 5, 7, 8, 9, 14)
como um filtro para o índice TimeStamp
, mas, ao analisar o plano de execução, ele não parece estar usando esse índice. Qualquer sugestão ou insight sobre isso seria muito apreciada.
Abaixo está o plano gráfico:
E aqui está um link para o arquivo .sqlplan .
Respostas:
Tabelas fornecidas da seguinte forma geral:
O seguinte índice é útil:
Para a consulta:
O filtro atende ao
AND
requisito da cláusula, a primeira chave do índice permite uma busca[TimeStamp]
pelo filtroEventTypeIDs
e a inclusão daDeviceID
coluna faz com que o índice cubra (porqueDeviceID
é necessário para a associação àDevice
tabela).A segunda chave do índice -
EventTypeID
não é estritamente necessária (também pode ser umaINCLUDEd
coluna); Eu o incluí na chave pelos motivos expostos aqui . Em geral, aconselho as pessoas a pelo menosINCLUDE
colunas de umaWHERE
cláusula de índice filtrado .Com base no plano atualizado de consulta e execução da pergunta, concordo que o índice mais geral sugerido pelo SSMS é provavelmente a melhor opção aqui, a menos que a lista de filtros
EventTypeIDs
seja estática, como Aaron também menciona em sua resposta:Índice sugerido (declare-o exclusivo, se apropriado):
Informações de cardinalidade do plano de execução (sintaxe não documentada, não use em sistemas de produção):
Consulta atualizada (repetir a
IN
lista daEventType
tabela ajuda o otimizador neste caso específico):Plano de execução estimado:
O plano que você obtém provavelmente será diferente porque estou usando estatísticas adivinhadas. O ponto geral é fornecer ao otimizador o máximo de informações possível e fornecer um método de acesso eficiente (índice) na
[Event]
tabela de 4 milhões de linhas .fonte
A maior parte do custo é a verificação de índice em cluster e, a menos que essa tabela seja realmente ampla ou você não precise de todas essas colunas na saída, acredito no SQL Server que este é o caminho ideal no cenário atual sem mais nada alterado . Ele usa uma varredura de intervalo (rotulada como uma busca de IC) para restringir o intervalo de linhas em que está interessado, mas, devido à saída, ainda será necessária uma pesquisa ou uma varredura de IC, mesmo com o índice filtrado que você criou. é direcionado para esse intervalo e, mesmo nesse caso, a verificação de IC provavelmente ainda é mais barata (ou pelo menos o SQL Server calcula como tal).
O plano de execução informa que esse índice seria útil:
Embora, dependendo da inclinação dos dados, seja melhor o contrário, por exemplo:
Mas eu testaria ambos para ter certeza de qual é o melhor - a diferença entre um desses índices e o que você tem agora pode ser apenas marginal (muitas variáveis para nós sabermos) e você deve levar em conta que um adicional O índice requer manutenção extra e isso pode afetar visivelmente suas operações DML (inserir / atualizar / excluir). Você também pode considerar incluir os critérios de filtro nesse índice, conforme sugerido por @SQLKiwi , mas apenas se esse for o conjunto de valores de EventTypeID que você pesquisa com freqüência. Se esse conjunto for alterado com o tempo, o índice filtrado será útil apenas para esta consulta específica.
Com uma contagem tão baixa de fileiras, tenho que me perguntar o quão ruim o desempenho poderia ser atualmente? Essa consulta retorna três linhas (mas não há indicação de quantas linhas foram rejeitadas). Quantas linhas na tabela?
fonte
Acabei de descobrir que o SQL Server 2008 R2 realmente fez uma sugestão de índice quando executei o plano de execução. Esse índice sugerido torna a consulta executada 90% mais rápida.
O índice sugerido foi o seguinte:
fonte