Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 为什么要对已排序的非聚集索引字段进行排序?_Sql Server - Fatal编程技术网

Sql server 为什么要对已排序的非聚集索引字段进行排序?

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 我参

假设我有一个带有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
我参与了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;