Sql server 查询性能悖论:唯一聚集索引与非唯一非聚集索引

Sql server 查询性能悖论:唯一聚集索引与非唯一非聚集索引,sql-server,indexing,sql-server-2012,query-performance,sql-server-performance,Sql Server,Indexing,Sql Server 2012,Query Performance,Sql Server Performance,我有一个表MY_table,大约有900万行 该表共有38列。与我的问题相关的栏目有: 记录\u ID:标识,带唯一聚集索引的bigint 创建的记录:日期时间,具有非唯一和非聚集索引 现在,我运行以下两个查询,自然希望第一个查询执行得更快,因为数据是按具有唯一聚集索引的列排序的,但不知何故,它执行得慢271倍(!) 执行时间分别为1630毫秒和6毫秒 请告知 p.S.:由于环境的安全策略,我无法查看执行计划或使用SQL ProfilerSQL Server有一些关于如何执行此查询的选择。它

我有一个表
MY_table
,大约有900万行

该表共有38列。与我的问题相关的栏目有:

  • 记录\u ID
    :标识,带唯一聚集索引的bigint
  • 创建的记录
    :日期时间,具有非唯一和非聚集索引
现在,我运行以下两个查询,自然希望第一个查询执行得更快,因为数据是按具有唯一聚集索引的列排序的,但不知何故,它执行得慢271倍(!)

执行时间分别为1630毫秒和6毫秒

请告知


p.S.:由于环境的安全策略,我无法查看执行计划或使用
SQL Profiler

SQL Server有一些关于如何执行此查询的选择。它可以首先对所有项目进行排序,利用您提到的索引,然后过滤掉与WHERE子句不匹配的任何项目。但是,通常来说,减少首先处理的数据集的大小会更快,因此不必对那么多的项进行排序

因此,SQL Server最有可能选择先执行
WHERE
过滤器。执行此操作时,很可能首先使用创建的记录_上的非唯一、非聚集索引跳过创建的记录_小于“20140801”的所有项目,然后获取该记录_之后的所有项目


此时,所有项目都按照在记录创建的索引中找到它们的顺序预先排序,因此第二次查询不需要额外的工作,但第一次查询必须对已选择的记录执行排序。

第二次查询只是一次直接的索引搜索。读取大于或等于搜索点的第一行,如果索引未覆盖,则可能进行单次查找。在您的情况下,索引将覆盖NCI,因为NCI始终包含CI键,因此无需查找。@MartinSmith,我真的很抱歉,但我没有完全理解您的评论。你能再解释一下吗?回答也是受欢迎的。因为我不在电脑上,所以我不会费心提交答案。一般来说,范围搜索可以满足
记录创建>='20140801
。在索引中找到相关点,然后沿其扫描。因为您只需要索引顺序中的前1行,SQL Server可以在读取第一行后立即停止范围查找。您的选择列表实际上位于不同的列
record\u id
,但由于它是聚集索引键,因此也会以静默方式包含在非聚集索引中。如果引擎决定先排序怎么办?另一种选择会更快吗?我认为不是,第二个选项会更快,对吗?我不是DB优化的向导,但我想这取决于几个因素,比如表中有多少项与WHERE子句匹配。
SELECT TOP 1 
    RECORD_ID 
FROM 
    MY_TABLE 
WHERE 
    RECORD_CREATED >= '20140801' 
ORDER BY 
    RECORD_ID

SELECT TOP 1 
    RECORD_ID 
FROM 
    MY_TABLE 
WHERE 
    RECORD_CREATED >= '20140801' 
ORDER BY 
    RECORD_CREATED