Azure SQL数据库左连接循环与150万条记录
我有表Customer_AJ(客户varchar,项目编号,购买日期时间),我有两个表与它成功和失败,我希望所有没有成功的失败在该客户的未来30分钟内。Azure SQL数据库左连接循环与150万条记录
我试了一下BYS使用不存在的,但它是在hashMatch得到循环(正如我在queryplan看到它,荫连接查询和执行计划的屏幕截图..
with Failure as (
select * from [dbo].[Customer_AJ] where item in (20, 34, 35, 36, 37, 47, 53, 54)
) ,
success as (
select * from Customer_AJ where Item in (1, 3, 40, 42, 43, 5)
) ,
final as (
select f.customer, f.item,f.purchase from Failure f left outer join success s
on f.customer = s.customer and DATEDIFF(minute , f.purchase , s.purchase) between 0 and 30
where s.customer is NULL
)
select * from final
核心问题将是对列DATEDIFF函数。这将导致扫描。如果你有几百万行,这是怎么回事慢每次都可以。你需要找到一种方法来加入数据不应用该功能。
完整的执行计划可能有其他建议,而不是图像。
有什么办法能去掉DATEDIFF函数。特别是这个条件连接? –
我不知道推动这一点的业务规则,但计算日期和时间值作为变量,然后与每个列的变量进行比较将是实现这一目标的一种方式。如果规则是要找到一个30分钟关等,然后弄清楚如何捕捉值,而在WHERE计算,ON或HAVING查询的WHERE子句。 –
个人,寻找的东西做的时候不存在,我更愿意用“明显” WHERE NOT EXISTS()
语法。查询优化器将使用相同的计划为LEFT OUTER JOIN ... WHERE field IS NULL
语法,但它是如此更容易阅读。
SELECT f.customer, f.item, f.purchase
FROM Failure f
WHERE NOT EXISTS (SELECT *
FROM Success s
WHERE s.customer = f.customer
AND DATEDIFF(minute , f.purchase , s.purchase) between 0 and 30)
的DateDiff()
在这里是性能杀手,因为没有办法让对匹配数据的快速通道,也可以优化预测有多少行匹配。为了解决这个问题,你可以尝试到DateDiff()
转换为DateAdd()
建设:
SELECT f.customer, f.item, f.purchase
FROM Failure f
WHERE NOT EXISTS (SELECT *
FROM Success s
WHERE s.customer = f.customer
AND s.purchase >= f.purchase
AND s.purchase <= DateAdd(minute, +30, f.purchase))
假设你有一个具有以下字段您Customer_AJ
表的索引:customer, item, purchase
这应该使Failure
和Success
较快之间的连接。 (你可能想要试验和交换字段的顺序,因为它取决于你的数据是什么样子,但是因为我们有一个purchase
列的匹配范围,所以我很确定你想要保持最后一个)。
而不是实时查询统计的截图,通过实际执行计划XML到https://www.brentozar.com/pastetheplan/并添加链接到您的问题。 –