我刚刚开始研究通过索引优化查询,因为SQL数据正在快速增长.我查看了优化器如何通过SSMS中的执行计划处理我的查询,并注意到正在使用排序操作符.我听说排序操作符表示查询中的设计不好,因为可以通过索引过早地进行排序.下面是一个示例表和数据,与我正在执行的操作类似:
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
以下是一个示例查询:
SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
AND ([Type] = 0 OR [Type] = 1)
ORDER BY [Phone]
我创建了一个非聚集索引来帮助加快查询速度:
CREATE NONCLUSTERED INDEX IX_Store ON dbo.[Store]([ParentStoreId], [Type], [Phone])
要构建IX_Store索引,我从简单的谓词开始
[ParentStoreId] = 10
AND ([Type] = 0 OR [Type] = 1)
然后,我为ORDER BY和添加[Phone]
列,以覆盖SELECT输出
因此,即使在构建索引时,优化器仍然使用排序运算符(而不是索引排序),因为[Phone]
在[ParentStoreId]
和[Type]
之后排序.如果我从索引中删除[Type]
列并运行查询:
SELECT [Phone]
FROM [dbo].[Store]
WHERE [ParentStoreId] = 10
--AND ([Type] = 0 OR [Type] = 1)
ORDER BY [Phone]
当然,优化器不会使用排序操作符,因为[Phone]
是按[ParentStoreId]
排序的.
所以问题是,我如何创建一个索引来覆盖查询(包括[Type]
谓词),而不让优化器使用排序?
EDIT:个
我正在使用的表有2000多万行