Optimización de consultas SQL eliminando el operador Ordenar en el plan de ejecución
Acabo de empezar a buscar la optimización de mis consultas a través de índices porque los datos SQL están creciendo de manera grande y rápida. Observé cómo el optimizador está procesando mi consulta a través del plan de ejecución en SSMS y noté que se está utilizando un operador de clasificación. He oído que un operador de clasificación indica un mal diseño en la consulta, ya que la clasificación puede realizarse prematuramente a través de un índice. Así que aquí hay una tabla de ejemplo y datos similares a lo que estoy haciendo:
IF OBJECT_ID('dbo.Store') IS NOT NULL DROP TABLE dbo.[Store]
GO
CREATE TABLE dbo.[Store]
(
[StoreId] int NOT NULL IDENTITY (1, 1),
[ParentStoreId] int NULL,
[Type] int NULL,
[Phone] char(10) NULL,
PRIMARY KEY ([StoreId])
)
INSERT INTO dbo.[Store] ([ParentStoreId], [Type], [Phone]) VALUES (10, 0, '2223334444')
INSERT INTO dbo.[Store] ([ParentStoreId], [Type], [Phone]) VALUES (10, 0, '3334445555')
INSERT INTO dbo.[Store] ([ParentStoreId], [Type], [Phone]) VALUES (10, 1, '0001112222')
INSERT INTO dbo.[Store] ([ParentStoreId], [Type], [Phone]) VALUES (10, 1, '1112223333')
GO
Aquí hay una consulta de ejemplo:
SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
AND ([Type] = 0 OR [Type] = 1)
ORDER BY [Phone]
Creo un índice no agrupado para ayudar a acelerar la consulta:
CREATE NONCLUSTERED INDEX IX_Store ON dbo.[Store]([ParentStoreId], [Type], [Phone])
Para construir el índice IX_Store, empiezo con los predicados simples
[ParentStoreId] = 10
AND ([Type] = 0 OR [Type] = 1)
Luego agrego el[Phone]
columna para ORDER BY y para cubrir la salida SELECT
Así que incluso cuando se crea el índice, el optimizador todavía utiliza el operador Ordenar (y no el índice) porque[Phone]
se ordena DESPUÉS de[ParentStoreId]
Y[Type]
. Si elimino la[Type]
columna del índice y ejecute la consulta:
SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
--AND ([Type] = 0 OR [Type] = 1)
ORDER BY [Phone]
Entonces, por supuesto, el optimizador no utiliza el operador Ordenar porque[Phone]
está ordenado por[ParentStoreId]
.
ntonces, la pregunta es cómo puedo crear un índice que cubra la consulta (incluida la[Type]
predicado) y no hacer que el optimizador use una Clasificación?
EDITAR
La mesa con la que estoy trabajando tiene más de 20 millones de filas