1

テーブル A で 100 万行以上、テーブル B で 500 万行以上を処理する必要がある MySQL クエリに取り組んでいます。クエリは、テーブル A からすべての一意の人物を選択し、テーブル B の各人物の売上と内部結合します。インデックス必要に応じて両方のテーブルに設定されます。

ここでの目標は、テーブル B のデータを含むテーブル A のすべての一意の電子メール アドレスをテーブル C に追加することです。

これを行うための最も最適化された方法を探しています。指定された ID のレコードをプルするために使用されている REPLACE INTO クエリの選択部分が含まれています。これは、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
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 に答える