我删除了我的旧问题,以便更准确地了解我需要什么。
我们有一个包含许多较小查询的大查询。这个查询运行得非常好,直到它到达“having max”子句:
having
max
(
DateField
) < getdate() - @2_years_ago
有没有比拥有 max 更快的条款?因为这会导致索引扫描以及表中存在的数百万行不停地循环和循环。
我试图按 row_number 做,但没有运气。
我只是注意到这个相同的查询在具有相同结构的其他数据库上运行得很好。
只是这个(有趣的是行更少)它不起作用。
数据库在同一台服务器上。
您的主要问题似乎是基数估计不佳导致编译器重新排序连接。当您使用 时,这似乎发生得更多
OPTION (RECOMPILE)
,因为服务器正在做出不同的估计。您应该能够足够简化您当前的查询,以便编译器会发现它更容易
如果没有看到您的架构,很难准确地说出,但似乎您可以将
EXISTS
逻辑翻转到NOT EXISTS
.HAVING
来查找最大日期。您现有的查询有很多问题:
a
b
c
是愚蠢的别名,考虑使用更有意义的别名。[]
引用列名,而不是''
. 除非必须,否则不要引用。NOLOCK
像五彩纸屑一样四处飞溅,你希望用它来达到什么目的?它对数据完整性有非常严重的影响。考虑改用TABLOCK
提示或SNAPSHOT
隔离。EXISTS
子查询不需要选择任何东西,实际上它被忽略了。你可以这样做EXISTS (SELECT 1
。where b.[MerchantLogId] = a.[MerchantLogId] group by b.[MerchantLogId]
没有意义:您将始终只有一组,因此不需要group by
.NTFM_MerchantLog
子查询,因为它是由主键连接的。DATEADD
似乎您也可以通过连接所有表并使用
OR
(为此您仍然需要一些左连接)将三个子查询合并为一个。希望在进行所有这些改进之后,您应该会看到更好的性能