SQL 筛选最近的行时查询需要很长时间

SQL Query takes a long time when filtering recent rows

我有这个 SQL 查询,但我发现 运行 最多可能需要 11 秒。我真的很困惑,因为当我将日期选择更改为 2018 年日期时,它立即 returns。

查询如下:

select
    cv.table3ID, dm.Column1 ,dm.Column2, mm.Column1, 
    convert(varchar, cv.Date, 107) as Date, 
    mm.table2ID, dm.table1ID, mm.Column2,
    count(ctt.table4ID) as Total
from
    table1 dm
inner join 
    table2 mm on mm.table2ID = dm.table1ID
inner join 
    table3 cv on cv.table3ID = mm.table2ID
left join 
    table4 ct on ct.table4CVID = cv.table3ID
inner join 
    table4 ctt on ctt.table4MMID = mm.table2ID
where
    ctt.table4Date >= '2019-01-19'
    and ct.table4CVID is null  
    and dm.Column1 like '%Albert%'
    and cv.Column1 = 39505 
    and cv.Status = 'A'  
group by
    cv.table3ID, dm.Column1 ,dm.Column2, mm.Column1, 
    cv.Date, mm.table2ID, dm.table1ID, mm.Column2

我发现当我使用 ctt.table4Date >= '2018-01-19' 执行该查询时,响应是即时的。但是对于“2019-01-19”,它需要 11 秒。

最初,当我发现查询耗时 11 秒时,我认为这一定是索引问题,但我不确定它是否与索引有关,因为它对较旧的系统执行得很好日期。

我查看了具有不同日期的查询的执行计划,它们看起来完全不同。

关于为什么会发生这种情况有什么想法吗?跟更新统计有关系吗?

[更新]

下图是table4 ctt在2018年和2019年的执行计划对比。根据执行计划,2018年占运营商成本的43%,2019年占45%。 Execution Plan comparison of table4 ctt 2019 and 2018. Top is 2019, bottom is 208

这里的图片是table4 as ct再次执行计划的对比。同样在这里,顶部是 2019 年,底部是 2018 年。 Execution plan of table4 ct comparison 2019 and 2018. Top is 2019, bottom is 208

[更新 2]

以下是 SQL 执行计划:

使用“2018-01-19”作为日期时:https://www.brentozar.com/pastetheplan/?id=SyUh8xXQV

使用“2019-01-19”作为日期时:https://www.brentozar.com/pastetheplan/?id=rkELW1Q7V

问题很可能是从其他 table 返回更多行。您与 [更新] 链接的聚集索引扫描仅显示聚集索引搜索。

但是,您确实需要意识到调用索引查找的次数是 144 次。实际读取的行数是 8 位数字,这导致响应缓慢。

我猜当这对你来说工作正常时,这个 table 的实际执行次数将是 1。144 在这里杀了你;给穷求谓词。如果您知道适用于您的查询计划,并且索引已经存在以支持它,您应该 forceseek 计划并给出明确的提示以按特定顺序加入。

编辑

查看共享计划,将日期更改为 2018 年对您来说效果更快,因为考虑到正在处理的数据量,SQL 切换到使用哈希匹配代替循环连接。