Sql server 为什么要对已排序的非聚集索引字段进行排序?
假设我有一个带有ID、名称和日期的表 我有一个非聚集索引,比如Sql server 为什么要对已排序的非聚集索引字段进行排序?,sql-server,Sql Server,假设我有一个带有ID、名称和日期的表 我有一个非聚集索引,比如 CREATE NONCLUSTERED INDEX IX_Test_NameDate ON [dbo].[Test] (Name, Date) 当我运行查询时 select [Name], [Date] from [dbo].[Test] WITH (INDEX(IX_Test_NameDate)) where [Name] like 'A%' order by [Date] asc 我参
CREATE NONCLUSTERED INDEX IX_Test_NameDate ON [dbo].[Test] (Name, Date)
当我运行查询时
select
[Name], [Date]
from
[dbo].[Test] WITH (INDEX(IX_Test_NameDate))
where
[Name] like 'A%'
order by
[Date] asc
我参与了SQL Server的执行计划
Select <-- Sort <-- Index Seek (NonClustered)
在这种情况下,日期不应该排序吗?不,日期列不是“已经在非聚集索引中排序”,至少不是单独排序。它在
名称
之后排序
考虑以下琐碎的表数据:
Name Date
----- --------
Allen 1/1/2014
Barb 1/1/2013
Charlie 1/1/2015
Darlene 1/1/2012
Ernie 1/1/2016
Faith 1/1/2011
按名称
排序后,日期
列可能会出现顺序错误。只有具有相同名称的行才能按顺序保证日期
你们的目标彼此有交叉的目的。您需要多个名称——因此数据最好按名称排序,这样就可以进行查找,但是您需要按日期排序。您建议如何存储上述六行表,以便按日期对每个可能的名称范围进行排序
如果名称的范围有某种规律性或模式(例如,您可能总是仅按首字母拉取名称),那么可能存在一种解决方法
ALTER TABLE dbo.Test ADD NamePrefix AS (Left(Name, 1)) PERSISTED;
CREATE NONCLUSTERED INDEX IX_Test_NamePrefix_Date ON dbo.Test (NamePrefix, Date);
现在,理论上此查询不需要执行排序:
SELECT Name, Date
FROM dbo.Test
WHERE NamePrefix = 'A'
ORDER BY Date;
请注意,添加这样一个持久化的计算列可能会遇到一些问题:数据大小的增加,这种设计几乎肯定在所有情况下都是错误的,计算列的增加将非常糟糕,等等
另外,手动强制索引通常不是最佳做法——由优化器选择。所需的排序,因为其中[Name]如“A%”
返回以A开头的行,并且您希望结果集按日期进行排序。它不需要对[code>进行排序,其中[Name]=[Date]asc之前的“whatever”订单
。
SELECT Name, Date
FROM dbo.Test
WHERE NamePrefix = 'A'
ORDER BY Date;