0

我使用的是 MySQL 5.0,我需要微调这个查询。谁能告诉我在这方面我能做些什么调整?

SELECT DISTINCT(alert_master_id) FROM alert_appln_header 
WHERE created_date < DATE_SUB(CURDATE(), INTERVAL (SELECT parameters FROM schedule_config WHERE schedule_name = "Purging_Config") DAY)
AND alert_master_id NOT IN (
SELECT DISTINCT(alert_master_id) FROM alert_details 
WHERE end_date IS NULL AND created_date < DATE_SUB(CURDATE(), INTERVAL (SELECT parameters FROM schedule_config WHERE schedule_name = "Purging_Config") DAY) 
UNION
SELECT DISTINCT(alert_master_id) FROM alert_sara_header 
WHERE sara_master_id IN 
(SELECT alert_sara_master_id FROM alert_sara_lines 
WHERE end_date IS NULL) AND created_date < DATE_SUB(CURDATE(), INTERVAL (SELECT parameters FROM schedule_config WHERE schedule_name = "Purging_Config") DAY)
) LIMIT 5000;
4

2 回答 2

4

我要做的第一件事是将子查询重写为 joins

SELECT      h.alert_master_id

FROM        alert_appln_header h

       JOIN schedule_config c
         ON c.schedule_name = 'Purging_Config'

  LEFT JOIN alert_details d
         ON d.alert_master_id = h.alert_master_id
        AND d.end_date IS NULL
        AND d.created_date < CURRENT_DATE - INTERVAL c.parameters DAY

  LEFT JOIN (
              alert_sara_header s
         JOIN alert_sara_lines  l
           ON l.alert_sara_master_id = s.sara_master_id
            )
         ON s.alert_master_id = h.alert_master_id
        AND s.end_date IS NULL
        AND s.created_date < CURRENT_DATE - INTERVAL c.parameters DAY

WHERE       h.created_date < CURRENT_DATE - INTERVAL c.parameters DAY
        AND d.alert_master_id IS NULL
        AND s.alert_master_id IS NULL

GROUP BY    h.alert_master_id

LIMIT       5000

如果之后仍然很慢,请重新检查您的索引策略。我建议索引:

  • alert_appln_header(alert_master_id,created_date)
  • schedule_config(schedule_name)
  • alert_details(alert_master_id,end_date,created_date)
  • alert_sara_header(sara_master_id,alert_master_id,end_date,created_date)
  • alert_sara_lines(alert_sara_master_id)
于 2014-01-31T09:56:37.183 回答
1

好的,这可能只是在黑暗中拍摄,但我认为你不需要这么多DISTINCT

SELECT DISTINCT(alert_master_id) FROM alert_appln_header 
WHERE created_date < DATE_SUB(CURDATE(), INTERVAL (SELECT parameters FROM schedule_config WHERE schedule_name = "Purging_Config") DAY)
AND alert_master_id NOT IN (
     -- removed distinct here --
    SELECT alert_master_id FROM alert_details 
    WHERE end_date IS NULL AND created_date < DATE_SUB(CURDATE(), INTERVAL (SELECT parameters FROM schedule_config WHERE schedule_name = "Purging_Config") DAY) 
    UNION
     -- removed distinct here --
    SELECT alert_master_id FROM alert_sara_header 
    WHERE sara_master_id IN 
        (SELECT alert_sara_master_id FROM alert_sara_lines 
        WHERE end_date IS NULL) 
    AND created_date < DATE_SUB(CURDATE(), INTERVAL (SELECT parameters FROM schedule_config WHERE schedule_name = "Purging_Config") DAY)
) LIMIT 5000;

由于使用DISTINCT非常昂贵,请尽量避免使用它。在第一WHERE个子句中,您要检查的idsNOT在 some result内,因此在该结果中someids出现多次并不重要。

于 2014-01-31T09:56:23.290 回答