Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Otimizando consultas SQL removendo o operador Sort no plano de execução


Primeiro, você deve verificar se a classificação é realmente um gargalo de desempenho. A duração da classificação dependerá do número de elementos a serem classificados e o número de armazenamentos para um armazenamento pai específico provavelmente será pequeno. (Isso supondo que o operador de classificação seja aplicado após a aplicação da cláusula where).

Isso é uma generalização excessiva. Frequentemente, um operador de classificação pode ser movido trivialmente para o índice e, se apenas as primeiras duas linhas do conjunto de resultados forem buscadas, pode reduzir substancialmente o custo da consulta, porque o banco de dados não precisa mais buscar todas as linhas correspondentes (e classificá-las all) para encontrar os primeiros, mas pode ler os registros na ordem do conjunto de resultados e parar quando registros suficientes forem encontrados.

No seu caso, você parece estar buscando todo o conjunto de resultados, portanto, é improvável que a classificação torne as coisas muito piores (a menos que o conjunto de resultados seja enorme). Além disso, no seu caso, pode não ser trivial construir um índice classificado útil, porque a cláusula where contém um ou.

Agora, se você ainda quiser se livrar desse operador de classificação, tente:
SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
AND [Type] in (0, 1)
ORDER BY [Phone]    

Como alternativa, você pode tentar o seguinte índice:
CREATE NONCLUSTERED INDEX IX_Store ON dbo.[Store]([ParentStoreId], [Phone], [Type])

para tentar fazer com que o otimizador de consulta faça uma verificação de intervalo de índice em ParentStoreId somente e, em seguida, verifique todas as linhas correspondentes no índice, exibindo-as se Type fósforos. No entanto, é provável que isso cause mais E/S de disco e, portanto, reduza a velocidade da consulta em vez de acelerá-la.

Editar :Como último recurso, você pode usar
SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
AND [Type] = 0
ORDER BY [Phone]

UNION ALL

SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
AND [Type] = 1
ORDER BY [Phone]

com
CREATE NONCLUSTERED INDEX IX_Store ON dbo.[Store]([ParentStoreId], [Type], [Phone])

e ordenar as duas listas no servidor de aplicação, onde você pode mesclar (como no merge sort) as listas pré-ordenadas, evitando assim uma ordenação completa. Mas isso é realmente uma micro-otimização que, embora acelere a classificação em uma ordem de magnitude, provavelmente não afetará muito o tempo total de execução da consulta, pois eu esperaria que o gargalo fosse a E/S de rede e disco, especialmente à luz do fato de que o disco fará muitos acessos aleatórios, pois o índice não está em cluster.