Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.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索引;取消排序的命令_Sql_Sql Server_Performance - Fatal编程技术网

分区+;的正确SQL索引;取消排序的命令

分区+;的正确SQL索引;取消排序的命令,sql,sql-server,performance,Sql,Sql Server,Performance,我有一个SQL语句,我正试图优化它以删除排序运算符 SELECT *,ROW_NUMBER() OVER ( PARTITION BY RuleInstanceId ORDER BY [Timestamp] DESC ) AS rn FROM RuleInstanceHistoricalMembership 我读到的所有内容都表明这是添加的正确索引,但它似乎没有任何效果 CREATE NONCLUSTERED INDEX IX_MyIndex ON db

我有一个SQL语句,我正试图优化它以删除排序运算符

SELECT *,ROW_NUMBER() OVER (
        PARTITION BY RuleInstanceId 
        ORDER BY [Timestamp] DESC
   ) AS rn
FROM RuleInstanceHistoricalMembership
我读到的所有内容都表明这是添加的正确索引,但它似乎没有任何效果

CREATE NONCLUSTERED INDEX IX_MyIndex ON dbo.[RuleInstanceHistoricalMembership](RuleInstanceId, [Timestamp] DESC)


我一定是漏掉了什么,因为我读过大量的文章,这些文章似乎都建议跨两列的索引应该可以解决这个问题

从技术上讲,您添加的索引确实允许您避免排序

但是,您创建的索引是非覆盖的,因此SQL Server还需要执行6000万个键查找,以返回基表

简单地扫描聚集索引并对其进行动态排序的成本要比该选项低得多

为了得到自动使用的索引,您需要执行以下操作之一

  • 从查询
    SELECT
    列表中删除列,以便索引覆盖它
  • 在索引中添加
    包含
    -d列
顺便说一句:对于一个有6000万行的表,您可能会发现,即使您尝试在非覆盖索引上使用索引提示来强制解决问题,您仍然无法获得避免排序的预期结果

CREATE TABLE RuleInstanceHistoricalMembership
  (
     ID             INT PRIMARY KEY,
     Col2           INT,
     Col3           INT,
     RuleInstanceId INT,
     [Timestamp]    INT
  )

CREATE NONCLUSTERED INDEX IX_MyIndex
  ON dbo.[RuleInstanceHistoricalMembership](RuleInstanceId, [Timestamp] DESC)

/*Fake small table*/
UPDATE STATISTICS RuleInstanceHistoricalMembership 
                  WITH ROWCOUNT = 600, 
                       PAGECOUNT = 10 

SELECT *,
       ROW_NUMBER() OVER ( PARTITION BY RuleInstanceId 
                               ORDER BY [Timestamp] DESC ) AS rn
FROM   RuleInstanceHistoricalMembership WITH (INDEX = IX_MyIndex) 
给出了计划

不排序,但增加行数和页数

/*Fake large table*/
UPDATE STATISTICS RuleInstanceHistoricalMembership 
                  WITH ROWCOUNT = 60000000, 
                       PAGECOUNT = 10000000 
再试一次,你就会得到

现在它有两种类型

NCI上的扫描顺序为
RuleInstanceId,Timestamp DESC
,但随后SQL Server根据将其重新排序为聚集索引键顺序(
Id ASC


这一步是尝试减少对聚集索引进行6000万次随机查找的预期巨大成本。然后将其重新排序为原始的
RuleInstanceId,Timestamp DESC
顺序,索引将其交付。

select*
更改为
select RuleInstanceId,Timestamp
@1\u CR时会发生什么,使其消失,我是否也需要索引来跨越所有选定的列?使用
select*
,优化器基本上可以选择对非聚集索引的每一行进行聚集索引搜索和对整个表进行扫描—选择后者可能是合理的。您可以通过“include”列将所有其他列作为“payload”添加到非聚集索引中,以避免访问聚集索引,但在不了解更多数据量等信息的情况下,很难知道这是否明智choice@1_CR这是一个表,我希望它包含数亿行,有5列(long guid int bit datetimeoffset),还有其他替代方法吗?@LukeMcGregor表中当前有多少数据?感谢堆的回答,我对SQL为什么现在不选择我的索引有了更深入的理解,非常感谢