1

我正在处理一个 MySQL 查询,该查询需要遍历表 A 中的 1+ 百万行和表 B 中的 5+ 百万行。该查询从表 A 中选择所有唯一的人,并与表 B 上每个人的销售额进行内部联接。索引必要时在两个表上设置。

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

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

对于子查询,我也有完全相同的查询,使用 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
4

1 回答 1

1

将您的子选择移动到连接应该会产生一些性能提升:

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
于 2013-09-22T09:15:30.120 回答