查询速度在WHERE子句中的两个“=”比较中下降

时间:2017-10-12 10:37:39

标签: mysql performance join

我有一个音乐数据库,其中包含发布和发布标题的表格。此“releases_view”获取标题/ title_id以及曲目的替代标题/替代title_id。这是视图的代码:

SELECT
    t1.`title` AS title,
    t1.`id` AS title_id,
    t2.`title` AS title_alt,
    t2.`id` AS title_alt_id

FROM
    releases

LEFT JOIN titles t1 ON t1.`id`=`releases`.`title_id`
LEFT JOIN titles t2 ON t2.`id`=`releases`.`title_alt_id`

联接表格中的title_idtitle_alt_id字段均为int(11)titletitle_alt为varchars。

问题

此查询将花费不到1毫秒:

SELECT * FROM `releases_view` WHERE title_id=12345

此查询也将花费不到1毫秒:

SELECT * FROM `releases_view` WHERE title_id=12345 OR title_alt_id!=54321

BUT:此查询将花费0.2秒。 慢了200倍!

SELECT * FROM `releases_view` WHERE title_id=20956 OR title_alt_id=38849

我很快就在WHERE子句中使用“=”进行了两次比较,事情确实变得很慢(尽管所有查询只有几个结果)。

你能帮我理解发生了什么吗?

修改

'EXPPL'显示了title_alt_id的USING WHERE,但我不明白为什么。我怎么能避免这个?

**编辑** 这是EXPLAIN DUMP。

id  select_type     table       partitions  type    possible_keys   key     key_len ref                         rows    Extra 
1   SIMPLE          releases    NULL        ALL     NULL            NULL    NULL    NULL                        76802   Using temporary; Using filesort
1   SIMPLE          t1          NULL        eq_ref  PRIMARY         PRIMARY 4       db.releases.title_id        1    
1   SIMPLE          t2          NULL        eq_ref  PRIMARY         PRIMARY 4       db.releases.title_alt_id    1       Using where

1 个答案:

答案 0 :(得分:0)

“非常慢”是因为优化程序与OR无法正常工作。

计划A(优化程序):扫描整个表格,评估整个OR

计划B:“索引合并联盟”可用于title_id = 20956 OR title_alt_id = 38849 ,如果您在title_idtitle_alt_id中有单独的索引:使用每个索引获取两个PRIMARY KEYs列表和“合并”列表,然后到达表格以获取*。多个步骤,不便宜。所以很少使用B计划。

title_id = 12345 OR title_alt_id != 54321是一个谜,因为它应该返回大部分表。请提供EXPLAIN SELECT...

LEFT JOIN(与JOIN相对)需要假设“右”表中可能缺少该行。