0

我有表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/並添加鏈接到您的問題。 –

回答

1

核心問題將是對列DATEDIFF函數。這將導致掃描。如果你有幾百萬行,這是怎麼回事慢每次都可以。你需要找到一種方法來加入數據不應用該功能。

完整的執行計劃可能有其他建議,而不是圖像。

+0

有什麼辦法能去掉DATEDIFF函數。特別是這個條件連接? –

+0

我不知道推動這一點的業務規則,但計算日期和時間值作爲變量,然後與每個列的變量進行比較將是實現這一目標的一種方式。如果規則是要找到一個30分鐘關等,然後弄清楚如何捕捉值,而在WHERE計算,ON或HAVING查詢的WHERE子句。 –

0

個人,尋找的東西做的時候不存在,我更願意用「明顯」 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列的匹配範圍,所以我很確定你想要保持最後一個)。