即使存在覆盖索引,也会对分区表进行聚集索引扫描

jes*_*esi 3 performance sql-server optimization sql-server-2014 query-performance

我有一个基于 col1 int 分区的分区表。我还有一个覆盖索引,用于我尝试解决的查询。

https://www.brentozar.com/pastetheplan/?id=BkNrNdgHm

以上是计划

任其发展,SQL Server 决定对整个表进行聚集索引扫描,这显然很慢。如果我强制索引(如上面的计划),查询会快速运行。

SQL Server 使用什么魔术逻辑来确定覆盖索引没有用?我不确定 top/orderby 和 rowgoal 是否与它有关。

我的表结构是

Create table object2(col1 int, col3 datetime, col4 int, col5, col6 etc) clusterd on col1

nonclustered non aligned index is on col3,col4 (col1 is clustered so its included in nonclust)

SELECT top(?) Object1.Column1
    FROM Object2 Object1 WITH (NOLOCK,index(Column2))
    WHERE  Object1.Column3 >= ?
    AND Object1.Column4 IN (?)
    ORDER BY Object1.Column1
Run Code Online (Sandbox Code Playgroud)

编辑添加的回购

    CREATE PARTITION FUNCTION [PFtest](int) AS RANGE RIGHT FOR VALUES (100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000)
    GO
    CREATE PARTITION SCHEME [PStest] AS PARTITION [PFtest] all TO ([PRIMARY]);
    GO

    create table test([ID] [int] IDENTITY(1,1) NOT NULL primary key clustered,[Created] [datetime] NULL,[Type] [int] NULL,text1 varchar(10),text2 varchar(20))
    on pstest(id)
    set nocount on

    declare @a int =1
    declare @type int
    while 1=1
    begin
    if @a%30 =0
    insert into test (Created, Type, text1, text2) select getdate(),4,'four','four'
    else
    insert into test (Created, Type, text1, text2) select getdate(),1,'one','one'
    set @a=@a+1
    end
    create nonclustered index ncl1 on test(created, type)

select min(created),max(created) from test
--2018-08-02 22:46:40.187   2018-08-02 22:49:01.577
SELECT top(10) ID
    FROM test  
    WHERE  Created >= '2018-08-02 22:49:01'
    AND Type IN (1, 4)
    ORDER BY ID -- clustered index scan

SELECT top(10) ID
    FROM test  
    WHERE  Created >= '2018-08-02 22:49:01.577'
    AND Type IN (1, 4)
    ORDER BY ID-- index seek of ncl1
Run Code Online (Sandbox Code Playgroud)

Pau*_*ite 6

是的,这很可能是行目标问题。

SQL Server 评估扫描聚集索引(以避免排序)?将比在非聚集索引中搜索匹配项、对它们进行排序然后返回顶部?匹配项更快(此时扫描将停止)找到第一个匹配项。

在您的 SQL Server 版本上,您可以通过运行查询OPTION (QUERYTRACEON 4138)以禁用行目标来测试设置行目标是否是原因。

相关问答: