当另一个表变得更饱满时,sql查询非常慢

时间:2012-01-26 06:21:20

标签: mysql sql

我有以下查询,但是一段时间后,当用户开始在“ci_falsepositives”表中放入越来越多的项目时,它变得非常慢。 ci_falsepositives表包含来自ci_address_book的引用字段和来自ci_matched_sanctions的另一个引用字段。

如何创建新查询但仍能对每个字段进行排序。 例如,我仍然可以对“点击”或“匹配”进行排序

SELECT *, matches - falsepositives AS hits
  FROM (SELECT c.*, IFNULL(p.total, 0) AS matches, 
               (SELECT COUNT(*)
                  FROM ci_falsepositives n 
                 WHERE n.addressbook_id = c.reference
                   AND n.sanction_key IN 
                       (SELECT sanction_key FROM ci_matched_sanctions)
               ) AS falsepositives 
          FROM ci_address_book c 
          LEFT JOIN 
               (SELECT addressbook_id, COUNT(match_id) AS total 
                  FROM ci_matched_sanctions
                 GROUP BY addressbook_id) AS p 
            ON c.id = p.addressbook_id
       ) S
 ORDER BY folder asc, wholename ASC
 LIMIT 0,15

1 个答案:

答案 0 :(得分:0)

问题必须是SELECT COUNT(*) FROM ci_falsepositives子查询。可以使用ci_falsepositivesci_matched_sanctions之间的内部联接来编写该子查询,但优化器可能会为您执行此操作。但是,我认为您需要做的是将该子查询转换为“下一个查询输出”的FROM子句中的单独查询(即SELECT c.*, ...)。可能是,该查询正在被多次评估 - 这就是当人们向ci_falsepositives添加记录时会给您带来的伤害。您应该仔细研究查询计划。

也许这个查询会更好:

SELECT *, matches - falsepositives AS hits
  FROM (SELECT c.*, IFNULL(p.total, 0) AS matches, f.falsepositives
          FROM ci_address_book AS c
          JOIN (SELECT n.addressbook_id, COUNT(*) AS falsepositives
                  FROM ci_falsepositives    AS n
                  JOIN ci_matched_sanctions AS m
                    ON n.sanction_key = m.sanction_key
                 GROUP BY n.addressbook_id
               ) AS f
            ON c.reference = f.addressbook_id
          LEFT JOIN 
               (SELECT addressbook_id, COUNT(match_id) AS total 
                  FROM ci_matched_sanctions
                 GROUP BY addressbook_id) AS p 
            ON c.id = p.addressbook_id
       ) AS s
 ORDER BY folder asc, wholename ASC
 LIMIT 0, 15