2013-09-22 40 views
1

我正在研究MySQL查詢,需要經歷表A中超過1百萬行和表B中超過5百萬行。查詢選擇表A和內部聯接中的所有唯一人員表B上每個人的銷售額。如有必要,索引在兩個表上設置。緩慢的MySQL替換/複雜的查詢

這裏的目標是從表一的數據與來自表B中添加的所有不同的電子郵件地址到表C.

我要尋找最優化的方式做到這一點。包括正在使用的REPLACE INTO查詢的select部分,該查詢將拉取指定ID中的記錄。這是一個帶IN條件的簡單CASE語句。

我也有完全相同的查詢使用NOT IN和IN子查詢。那一次。

期待任何人都可以提供的幫助,並希望有更好的方式來做到這一點。

SELECT 
    c.Email, 
    MAX(c.Birthdate) 
    UPPER(c.Deleted) AS Deleted, 
    UPPER(c.Inactive) AS Inactive, 
    UPPER(c.SendEmail) AS SendEmail, 
    CONCAT('[',GROUP_CONCAT(DISTINCT c.Site SEPARATOR ']['),']') AS SITEID, 
    CONCAT('[',GROUP_CONCAT(DISTINCT c.Studio SEPARATOR ']['),']') AS STUDIO, 
    ( SELECT CONCAT('[',GROUP_CONCAT(DISTINCT s2.Service SEPARATOR ']['),']') 
     FROM my_example c2 
     INNER JOIN my_example_sales s2 ON s2.idMember = c2.idMember AND s2.Site = c2.Site WHERE c2.Email = c.Email 
    ) as SERVICES, 
    ( SELECT MAX(date(s1.Date)) as Date 
     FROM my_example_sales s1 
     WHERE s1.idMember = c.idMember 
AND s1.Site = c.Site 
     AND (CASE WHEN s1.Site = '1' THEN s1.ProductID IN ('1','6','7','12','18','22') 
     WHEN s1.Site = '2' THEN s1.ProductID = '156' 
     WHEN s1.Site = '3' THEN s1.ProductID IN ('3','5','6') 
     WHEN s1.Site = '4' THEN s1.ProductID IN ('11','15') 
     WHEN s1.Site = '5' THEN s1.ProductID = '23' 
     WHEN s1.Site = '6' THEN s1.ProductID = '23' 
     WHEN s1.Site = '7' THEN s1.ProductID = '23' 
    WHEN s1.Site = '8' THEN s1.ProductID = '23' 
    WHEN s1.Site = '9' THEN s1.ProductID = '23' 
    WHEN s1.Site = '10' THEN s1.ProductID IN ('7','11','17','30','31') 
    WHEN s1.Site = '11' THEN s1.ProductID = '23' 
    WHEN s1.Site = '12' THEN s1.ProductID IN ('7','11','17','30','31') 
     WHEN s1.Site = '13' THEN s1.ProductID = '23' END) 
     WHERE 1 
     ORDER BY s1.Date DESC 
     LIMIT 0,1 
    ) as lastPurchaseFreeWeek, 
    NOW() as dateModified 
FROM my_example c 
WHERE c.Email !='' 
GROUP BY c.Email 
ORDER BY c.ModDate DESC 

回答

0

移動你的子查詢到連接應該產生一些性能提升:

SELECT 
    c.Email, 
    MAX(c.Birthdate) 
    UPPER(c.Deleted) AS Deleted, 
    UPPER(c.Inactive) AS Inactive, 
    UPPER(c.SendEmail) AS SendEmail, 
    CONCAT('[',GROUP_CONCAT(DISTINCT c.Site SEPARATOR ']['),']') AS SITEID, 
    CONCAT('[',GROUP_CONCAT(DISTINCT c.Studio SEPARATOR ']['),']') AS STUDIO, 
    c2.SERVICES, 
    s1.`Date` as lastPurchaseFreeWeek, 
    NOW() as dateModified 
FROM my_example c 
INNER JOIN (
     SELECT CONCAT('[',GROUP_CONCAT(DISTINCT s2.Service SEPARATOR ']['),']') AS SERVICES 
     FROM my_example c2 
     INNER JOIN my_example_sales s2 ON s2.idMember = c2.idMember AND s2.Site = c2.Site 
    ) c2 ON c2.Email = c.Email 
INNER JOIN ( 
     SELECT MAX(date(s1.Date)) as `Date` 
     FROM my_example_sales s1 
     WHERE (CASE WHEN s1.Site = '1' THEN s1.ProductID IN ('1','6','7','12','18','22') 
       WHEN s1.Site = '2' THEN s1.ProductID = '156' 
       WHEN s1.Site = '3' THEN s1.ProductID IN ('3','5','6') 
       WHEN s1.Site = '4' THEN s1.ProductID IN ('11','15') 
       WHEN s1.Site = '5' THEN s1.ProductID = '23' 
       WHEN s1.Site = '6' THEN s1.ProductID = '23' 
       WHEN s1.Site = '7' THEN s1.ProductID = '23' 
       WHEN s1.Site = '8' THEN s1.ProductID = '23' 
       WHEN s1.Site = '9' THEN s1.ProductID = '23' 
       WHEN s1.Site = '10' THEN s1.ProductID IN ('7','11','17','30','31') 
       WHEN s1.Site = '11' THEN s1.ProductID = '23' 
       WHEN s1.Site = '12' THEN s1.ProductID IN ('7','11','17','30','31') 
       WHEN s1.Site = '13' THEN s1.ProductID = '23' END) 
    ) s1 ON (s1.idMember = c.idMember AND s1.Site = c.Site) 
WHERE c.Email !='' 
GROUP BY c.Email 
ORDER BY c.ModDate DESC 
+0

偉大的建議!應用所做的更改可縮短查詢時間30秒,但結果爲空。我還必須將s1.idMember,s1.Site,c.Email字段添加到內部聯接選擇中,因爲MySQL抱怨它們不存在。結果集可以預期爲〜640K記錄。 – nickCR