sql >> Base de Datos >  >> RDS >> Sqlserver

Optimización de consultas SQL eliminando el operador Ordenar en el plan de ejecución

Primero, debe verificar que la ordenación sea realmente un cuello de botella de rendimiento. La duración de la ordenación dependerá de la cantidad de elementos que se ordenarán, y es probable que la cantidad de tiendas para una tienda principal en particular sea pequeña. (Eso suponiendo que el operador de clasificación se aplica después de aplicar la cláusula where).

Eso es una generalización excesiva. A menudo, un operador de ordenación se puede mover trivialmente al índice y, si solo se recuperan las dos primeras filas del conjunto de resultados, puede reducir sustancialmente el costo de la consulta, porque la base de datos ya no tiene que recuperar todas las filas coincidentes (y ordenarlas). all) para encontrar los primeros, pero puede leer los registros en el orden del conjunto de resultados y detenerse una vez que se encuentran suficientes registros.

En su caso, parece que está obteniendo el conjunto de resultados completo, por lo que es poco probable que ordenar eso empeore las cosas (a menos que el conjunto de resultados sea enorme). Además, en su caso, puede que no sea trivial crear un índice ordenado útil, porque la cláusula where contiene un or.

Ahora, si aún desea deshacerse de ese operador de clasificación, puede probar:

SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
AND [Type] in (0, 1)
ORDER BY [Phone]    

Alternativamente, puede probar el siguiente índice:

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

para intentar que el optimizador de consultas haga un escaneo de rango de índice en ParentStoreId solo, luego escanee todas las filas coincidentes en el índice, imprimiéndolas si Type partidos. Sin embargo, es probable que esto provoque más E/S de disco y, por lo tanto, ralentice su consulta en lugar de acelerarla.

Editar :Como último recurso, podría 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]

con

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

y ordene las dos listas en el servidor de aplicaciones, donde puede combinar (como en la ordenación por combinación) las listas preordenadas, evitando así una ordenación completa. Pero eso es realmente una microoptimización que, si bien acelera la ordenación en sí misma en un orden de magnitud, es poco probable que afecte mucho el tiempo total de ejecución de la consulta, ya que esperaría que el cuello de botella fuera la red y la E/S del disco, especialmente a la luz del hecho de que el disco tendrá mucho acceso aleatorio ya que el índice no está agrupado.