为什么SQL生成一个低效的计划,并在此查询中添加了简单的OR条件?

时间:2016-08-25 21:47:19

标签: mysql sql

考虑一个包含2个表的MySQL数据库:成员跟随,其中以下是来自成员的以下关系的联接表对自己。

  • 成员是100k行
  • 以下是1.3米行

此查询速度非常快,可在< 1秒

select distinct m.id
from member m
 join following t1 on m.id = t1.to_member_id
 join following t2 on t1.from_member_id = t2.to_member_id
where (t2.from_member_id = 1)

但是,当我添加OR条件时

select distinct m.id
from member m
 join following t1 on m.id = t1.to_member_id
 join following t2 on t1.from_member_id = t2.to_member_id
where (t2.from_member_id = 1 OR m.id = 2)

查询在15秒内运行!

查询计划分别如下所示,

enter image description here

enter image description here

那么为什么这个简单的OR条件会如此彻底地改变计划呢?

我想成像服务器在内部只是联合两套?无论如何,我确实尝试了以下,确实查询再次快得多。

select distinct m.id
from member m
 join following t1 on m.id = t1.to_member_id
 join following t2 on t1.from_member_id = t2.to_member_id
where t2.from_member_id = 1 
union distinct
select m.id from m.id = 2

但无论如何我可以构造查询,但仍然使用OR条件,或以某种方式给它提示,以便它生成更好的计划?我问这个是因为实际的查询是由框架生成的,并不总是可以在union语句中包含多个子条件。

1 个答案:

答案 0 :(得分:0)

如果你不使用OR条件,mysql可以非常有效地使用索引,但是当你使用OR时,它实际上必须一个一个地评估它们,并且这个过程要慢得多,我建议使用两个查询和UNION它们。