左连接使查询变慢,是否有任何方法来提高此查询的速度

时间:2011-10-13 13:10:40

标签: mysql

select 
    b.entry_id,
    b.assign_id,
    a.profile_type,
    a.profile_id,
    a.profile_name,
    a.profile_status,
    b.entry_type,
    b.assign_id,
    c.chapter_name,
    d.section_name,
    h.group_name,
    i.programme_name,
    k.subjectprogramme_name,
    j.masterprogramme_name,
    l.developmentprogramme_name
from profile_master a
left join profile_assign b on (a.profile_id = b.profile_id)  
left join chapter_master c 
       on (b.entry_id = c.chapter_id and b.entry_type='chapter') 
left join section_master d 
       on (b.entry_id = d.section_id and b.entry_type='section')
left join group_master h 
       on (b.entry_id = h.group_id and b.entry_type='Group' 
           and h.year_id='".$this->year."')
left join programme_master i 
       on (b.entry_id = i.programme_id and b.entry_type='Programme' 
           and i.year_id='".$this->year."')
left join subjectprogramme_master k 
       on (b.entry_id = k.subjectprogramme_id and b.entry_type='subjectProgramme' 
           and k.year_id='".$this->year."')
left join masterprogramme_master j 
       on (b.entry_id = j.masterprogramme_id and b.entry_type='masterProgramme' 
           and j.year_id='".$this->year."')
left join developmentprogramme_master l 
       on (b.entry_id = l.developmentprogramme_id 
           and b.entry_type='developmentProgramme')

3 个答案:

答案 0 :(得分:0)

1)摆脱左连接的条件。使用WHERE子句进行过滤

2)我猜UNION或7个查询(分别由每个实体分别)在你的情况下会好得多

答案 1 :(得分:0)

如果没有直接访问数据库,这是一个难以回答的问题,所以我会尝试一般的答案!

  • 在此查询中使用“explain”以查看MySQL是否建议了一些索引。毫无疑问,它会提示一些,因为你几次访问几个列,并且索引通常会改善甚至最慢的OUTER JOIN
  • 您正在对$this->year使用大量检查,因此这会建议一些复合索引,例如programme_id year_id都在同一个索引中

当然,有些解决方案可能取决于您如何使用输出,例如:

  • 如果此查询经常运行足以成为等待它的用户的问题,但很少有延迟不成为问题(例如,可以根据昨晚的数据运行它),您可以在一夜之间运行它缓存结果。

答案 2 :(得分:0)

当条件通过时,你真的只做一个连接,我建议做这样的子选择:

SELECT 
    b.entry_id, 
    b.assign_id, 
    a.profile_type, 
    a.profile_id, 
    a.profile_name, 
    a.profile_status, 
    b.entry_type, 
    b.assign_id, 
    CASE b.entry_type 
    WHEN 'chapter' THEN SELECT(c.chapter_name FROM c WHERE b.entry_id = c.chapter_id)
    WHEN 'section' THEN SELECT(d.section_name FROM d WHERE b.entry_id = d.section_id)
    WHEN ....
    END as name
from profile_master a 
left join profile_assign b on (a.profile_id = b.profile_id)   

如果你坚持让输出相同,那么你需要将这个选择包装在外部选择中,如下所示:

SELECT 
  entry_id, assign_id, ......
  , CASE entry_type WHEN 'chapter' THEN name ELSE null END as chapter_name
  , CASE entry_type WHEN 'section' THEN name ELSE null END as section_name
FROM
  (select statement like above) sub