慢MySQL替换/复杂查询

时间:2013-09-22 08:49:01

标签: mysql performance mysqlimport

我正在开发一个MySQL查询,需要在表A中查看100多万行,在表B中查看500万行。查询选择表A中的所有唯一人和内部联接以及表中每个人的销售额B.必要时在两个表格上设置索引。

此处的目标是将表A中的所有唯一电子邮件地址与表B中的数据一起添加到表C中。

我正在寻找最优化的方法来做到这一点。包括正在使用的REPLACE INTO查询的选择部分,它将在指定的id中提取记录。这是一个简单的CASE语句,具有IN条件。

对于子查询,我也使用NOT IN vs 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

1 个答案:

答案 0 :(得分: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