2013-09-22 3 views
1

Я работаю над MySQL-запросом, который должен пройти 1+ миллионов строк в таблице A и 5+ миллионов в таблице B. Запрос выбирает всех уникальных людей из таблицы A и внутренних соединений с помощью продажи для каждого человека в таблице B. Индекс устанавливается на обе таблицы, где это необходимо.Slow MySQL replace/complex query

Цель здесь, чтобы добавить все уникальные адреса электронной почты из таблицы А с данными из таблицы B в таблице C.

Ищу наиболее оптимизированный способ сделать это. Включена выбранная часть используемого запроса REPLACE INTO, который будет вытаскивать записи в указанных идентификаторах. Это простой оператор 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 

ответ

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 жаловался на то, что они не существуют. Ожидается, что набор результатов составит ~ 640 тыс. Записей. – nickCR