多联接或子查询查询优化

Posted

技术标签:

【中文标题】多联接或子查询查询优化【英文标题】:Multiple Join or subquery query optimization 【发布时间】:2009-10-06 12:53:07 【问题描述】:

我有这个查询,对于给定的情况,它会在 1 或 2 秒内执行:

    Select Count(*) as qtty  
    From event e  
    Join org o On o.orgID = e.orgID  
    Join venue v On v.venueID = e.venueID  
    Where Match( e.name, e.description ) Against ( $keywords )  
        And e.site_id = $site_id  
        And e.display <> 0</code>

它计算行数以构建分页。当我引入按事件类型过滤(类型与事件多对多相关)时,查询开始花费不少于 45 秒:

    And Exists (   
      Select ete.id  
      From event_type_to_event ete   
      Where ete.event_id = e.eventID  
      And ete.event_type_id = $category )</code>

我也尝试过使用 event_type_to_event 加入,但速度更慢。 有什么建议吗?

注意:已解决。使用索引,查询执行时间减少到不到一秒。

【问题讨论】:

请粘贴EXPLAIN查询的结果 【参考方案1】:

我怀疑您需要在 event_type_to_event 表中的 event_type_id 列上添加索引,但如果那里已经有索引,请尝试以下操作:

Select Count(*) as qtty
From event e
   Join org o On o.orgID = e.orgID
   Join venue v On v.venueID = e.venueID
Where Match( e.name, e.description ) Against ( $keywords )
   And e.site_id = $site_id
   And e.display <> 0
   And Exists 
      (Select * From event_type_to_event 
       Where event_id = e.eventID
          And event_type_id = $category)

如果 Event_Id 是表 event_type_to_event 的 PK,您也可以尝试加入而不使用 Exists,

Select Count(*) as qtty
From event e
   Join org o On o.orgID = e.orgID
   Join venue v On v.venueID = e.venueID
   Join event_type_to_event t
       On t.event_id = = e.eventID
Where Match( e.name, e.description ) Against ( $keywords )
   And e.site_id = $site_id
   And e.display <> 0
   And t.event_type_id = $category

【讨论】:

谢谢!我不得不承认,这是我第一次真正看到使用索引的不同之处! (这样一个数据库新手)无论如何,第二个查询不起作用,因为 event_type_to_event 是一个“多对多”表,所以它也应该按事件 ID 分组,但我也试过了,没有索引,它更慢比子查询。谢谢!

以上是关于多联接或子查询查询优化的主要内容,如果未能解决你的问题,请参考以下文章

了解MySQL联表查询中的驱动表,优化查询,以小表驱动大表

多连接数百万条记录的优化查询需要建议

需要帮助来优化 ORACLE SQL 查询 [关闭]

优化按联接表中的字段对结果进行分组的查询

MySQL查询优化器工作原理解析

MySQL查询优化器工作原理解析