我应该为这个慢速多连接查询添加哪些索引?

Posted

技术标签:

【中文标题】我应该为这个慢速多连接查询添加哪些索引?【英文标题】:Which indexes should I add for this slow mulitple join query? 【发布时间】:2013-10-11 19:14:13 【问题描述】:

我需要找到会说某种特定语言并且未来可以在有效地点或教师的主要地点但不需要可以出现的主要地点的教师。多个教师可以在同一个位置。此查询有效,但速度很慢。我应该使用哪些索引?

Select
  teachers.teacher_id, 
  teacherLocations.location_id
From
  tdb_teachers AS teachers
Join 
  tdb_teacher_languages As teacherLanguages
    On teacherLanguages.teacher_id = teachers.teacher_id And
       teacherLanguages.language_id = 33
Left Join
  tdb_availability As locAvail
    On locAvail.teacher_id = teachers.teacher_id And
       locAvail.end_date >= 1381449600
Join
  tdb_locations AS teacherLocations
    On (
      teacherLocations.location_id = locAvail.location_id Or
      teacherLocations.location_id = teachers.location_id
   ) And
   teacherLocations.latitude != "" And
   teacherLocations.longitude != ""

【问题讨论】:

您应该始终检查索引是否放置在连接的任何内容上,或 where 子句中的任何内容上(在大多数情况下)。 请删除您的联接中的条件并使用WHERE 子句。 您是否尝试过 EXPLAIN 来找出瓶颈? 是的,没有一个连接使用索引。只有教师表使用 PRIMARY。 确保您在 tdb_teacher 语言.teacher_id 上有索引(您可以将 language_id 添加到同一个索引)同时确保您在 tdb_availability.teacher_id 上有索引(可能希望将 end_date 添加到该索引) 【参考方案1】:

先试试这是否能给你带来更好的结果:

Select
  teachers.teacher_id, 
  teacherLocations.location_id
From
  tdb_teachers AS teachers
Join 
  tdb_teacher_languages As teacherLanguages
    On teacherLanguages.teacher_id = teachers.teacher_id 
Left Join
  tdb_availability As locAvail
    On locAvail.teacher_id = teachers.teacher_id And
Join
  tdb_locations AS teacherLocations
    On (
      teacherLocations.location_id = locAvail.location_id Or
      teacherLocations.location_id = teachers.location_id
   ) 
WHERE
   teacherLocations.latitude != "" 
   And teacherLocations.longitude != ""
   AND locAvail.end_date >= 1381449600
   And teacherLanguages.language_id = 33

然后在非空字段上添加索引,看起来 tdb_teacher_languages.end_date 和 tdb_teacher_languages.language_id 是您的最佳选择。 之后,您可以尝试在此处粘贴解释计划。

【讨论】:

将逻辑移动到哪里而不是连接就可以了。谢谢!

以上是关于我应该为这个慢速多连接查询添加哪些索引?的主要内容,如果未能解决你的问题,请参考以下文章

子查询与连接

mysql 使用内部连接优化查询,其中和排序依据和坐标

减少连接查询的逻辑读取

在 WHERE 子句中使用 OR 的慢速 JOIN 查询 - 缺少可能的索引?

使用 or 优化查询

如何在单个查询中使用索引进行多表连接?