Otimizando consultas SQL removendo o operador Sort no plano de execução
Comecei a otimizar minhas consultas por meio de índices, porque os dados SQL estão crescendo de forma rápida e ampla. Examinei como o otimizador está processando minha consulta através do plano de execução no SSMS e notei que um operador de classificação está sendo usado. Ouvi dizer que um operador de classificação indica um design incorreto na consulta, pois a classificação pode ser feita prematuramente por meio de um índice. Então, aqui está uma tabela de exemplo e dados semelhantes ao que estou fazendo:
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
Aqui está um exemplo de consulta:
SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
AND ([Type] = 0 OR [Type] = 1)
ORDER BY [Phone]
Crio um índice não em cluster para ajudar a acelerar a consulta:
CREATE NONCLUSTERED INDEX IX_Store ON dbo.[Store]([ParentStoreId], [Type], [Phone])
Para criar o índice IX_Store, começo com os predicados simples
[ParentStoreId] = 10
AND ([Type] = 0 OR [Type] = 1)
Em seguida, adiciono o[Phone]
para ORDER BY e para cobrir a saída SELECT
Assim, mesmo quando o índice é criado, o otimizador ainda usa o operador Sort (e não a classificação do índice) porque[Phone]
é ordenado DEPOIS[ParentStoreId]
AND[Type]
. Se eu remover o[Type]
do índice e execute a consulta:
SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
--AND ([Type] = 0 OR [Type] = 1)
ORDER BY [Phone]
Então, é claro que o operador Sort não é usado pelo otimizador porque[Phone]
é classificado por[ParentStoreId]
.
Então, a questão é como posso criar um índice que cubra a consulta (incluindo o[Type]
predicado) e o otimizador não usa uma Classificação?
EDITAR
A tabela com a qual estou trabalhando tem mais de 20 milhões de linhas