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 

Here is the Query Execution plan for it

+1

而不是实时查询统计的截图,通过实际执行计划XML到https://www.brentozar.com/pastetheplan/并添加链接到您的问题。 –

核心问题将是对列DATEDIFF函数。这将导致扫描。如果你有几百万行,这是怎么回事慢每次都可以。你需要找到一种方法来加入数据不应用该功能。

完整的执行计划可能有其他建议,而不是图像。

+0

有什么办法能去掉DATEDIFF函数。特别是这个条件连接? –

+0

我不知道推动这一点的业务规则,但计算日期和时间值作为变量,然后与每个列的变量进行比较将是实现这一目标的一种方式。如果规则是要找到一个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这应该使FailureSuccess较快之间的连接。 (你可能想要试验和交换字段的顺序,因为它取决于你的数据是什么样子,但是因为我们有一个purchase列的匹配范围,所以我很确定你想要保持最后一个)。