我该如何优化这个mysql select + multiple join查询?

时间:2014-01-15 21:39:20

标签: mysql

我正在运行此查询,但速度非常慢。最后一个左连接的OR子句是什么让它陷入困境,但我无法找到另一种方法来构造查询以获得我正在寻找的结果:

SELECT *,
       DATE_FORMAT(tbl1.pub, '%m/%d/%Y') AS pub_a,
       CONCAT(tbl1.code1, tbl1.code2) AS code_a
FROM (tbl1
      INNER JOIN tbl2 ON tbl1.pkid=tbl2.fkid
      LEFT JOIN tbl3 ON tbl1.pkid=tbl3.fkid)
LEFT JOIN tbl4 ON tbl1.person=tbl4.code OR tbl3.person=tbl4.code
WHERE tbl1.subcat != ''
  AND tbl1.pub < '2014-01-15 13:20:23'
  AND tbl1.exp > '2014-01-15 13:20:23'
ORDER BY tbl1.pub DESC 
LIMIT 0, 50

2 个答案:

答案 0 :(得分:2)

不幸的是,在or子句中优化on并不容易。您可以将其拆分为两个查询,并结合union

select *
from ((SELECT *,
              DATE_FORMAT(tbl1.pub, '%m/%d/%Y') AS pub_a,
              CONCAT(tbl1.code1, tbl1.code2) AS code_a
        FROM (tbl1
              INNER JOIN tbl2 ON tbl1.pkid=tbl2.fkid
              LEFT JOIN tbl3 ON tbl1.pkid=tbl3.fkid
              )
              LEFT JOIN tbl4 ON tbl3.person=tbl4.code
        WHERE tbl1.subcat != ''
          AND tbl1.pub < '2014-01-15 13:20:23'
          AND tbl1.exp > '2014-01-15 13:20:23'
        ORDER BY tbl1.pub DESC 
        LIMIT 0, 50
       ) union
       (SELECT *,
              DATE_FORMAT(tbl1.pub, '%m/%d/%Y') AS pub_a,
              CONCAT(tbl1.code1, tbl1.code2) AS code_a
        FROM (tbl1
              INNER JOIN tbl2 ON tbl1.pkid=tbl2.fkid
              LEFT JOIN tbl3 ON tbl1.pkid=tbl3.fkid
              )
              LEFT JOIN tbl4 ON tbl1.person=tbl4.code
        WHERE tbl1.subcat != ''
          AND tbl1.pub < '2014-01-15 13:20:23'
          AND tbl1.exp > '2014-01-15 13:20:23'
        ORDER BY tbl1.pub DESC 
        LIMIT 0, 50
       )
      ) t
order by pub desc
limit 0, 50

答案 1 :(得分:1)

这是一个很长的镜头,但尝试更改

left join tbl4 on tbl1.person = tbl4.code
    or tbl3.person = tbl4.code

left join tbl4 on tbl4.code in (tbl1.person, tbl3.person)