2017-10-15 93 views
0

我試圖優化這個MySQL查詢,我想知道當前約會之前沒有預約的客戶數量,換句話說,if他們有一個約會(這是什麼NOT IN(子查詢正在檢查),然後排除它們。)優化一個MySQL NOT IN(查詢

但是,這個查詢是絕對殺死性能。我知道,MySQL不是非常好的查詢,但我無法確定優化此查詢的最佳方式,它需要15到30秒的時間才能運行,我已在CustNo,AptStatus和AptNum上創建了索引

SELECT 
     COUNT(*)    AS NumOfCustomersWithPriorAppointment, 
FROM 
     transaction_log AS tl 
LEFT JOIN 
     appointment AS a 
ON 
     a.AptNum = tl.AptNum 
INNER JOIN 
     customer AS c 
ON 
     c.CustNo = tl.CustNo 
WHERE 
     a.AptStatus IN (2) 
AND  a.CustNo NOT IN 
     (
       SELECT 
         a2.CustNo 
       FROM 
         appointment a2 
       WHERE 
         a2.AptDateTime < a.AptDateTime) 


AND  a.AptDateTime > BEGIN_QUERY_DATE 
AND  a.AptDateTime < END_QUERY_DATE 

預先感謝您。

+0

請爲您的查詢中的每個表提供'SHOW CREATE TABLE'語句。 –

+0

BEGIN_QUERY_DATE是常量嗎?或另一列?用'LEFT JOIN .. IS NULL'重寫查詢;告訴我們它是否更快。 –

+0

順便提一下,你的外部連接(a)實際上是一個內部連接 – Strawberry

回答

0

嘗試以下操作:

SELECT 
     COUNT(*)    AS NumOfCustomersWithPriorAppointment, 
FROM 
     transaction_log AS tl 
INNER JOIN 
     appointment AS a 
ON 
     a.AptNum = tl.AptNum 
LEFT OUTER JOIN appointment AS earlier_a 
     ON earlier_a.CustNo = a.CustNo 
     AND earlier_a.AptDateTime < a.AptDateTime 
INNER JOIN 
     customer AS c 
ON 
     c.CustNo = tl.CustNo 
WHERE 
     a.AptStatus IN (2) 
AND  earlier_a.AptNum IS NULL 


AND  a.AptDateTime > BEGIN_QUERY_DATE 
AND  a.AptDateTime < END_QUERY_DATE 

這將從一個綜合指數受益於(CustNo,AptDateTime)。使其具有唯一性,如果適合你的商業模式(邏輯上似乎像它應該的,但實際上它可能不會,這取決於你如何處理衝突在您的應用程序。)

提供SHOW CREATE TABLE報表中的所有表如果不創建充分的性能改進。

+0

這個查詢確切地指明瞭它。非常感謝您的幫助和建議! – 3C41DC