Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 为什么SQL会生成一个效率低下的计划,并将一个简单的或条件添加到此查询中?_Mysql_Sql - Fatal编程技术网

Mysql 为什么SQL会生成一个效率低下的计划,并将一个简单的或条件添加到此查询中?

Mysql 为什么SQL会生成一个效率低下的计划,并将一个简单的或条件添加到此查询中?,mysql,sql,Mysql,Sql,考虑一个MySQL数据库,它有两个表:成员,后续,其中后续是一个从成员到自身的后续关系的联接表 成员为10万行 以下是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

考虑一个MySQL数据库,它有两个表:成员后续,其中后续是一个从成员到自身的后续关系的联接表

  • 成员为10万行
  • 以下是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)
但是,当我添加一个或条件时

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秒内运行

查询计划分别如下所示:

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

我会想象服务器会在内部合并这两个集合?无论如何,我确实尝试了下面的方法,而且查询速度确实更快了

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语句中包含多个子条件。

如果不使用OR条件,mysql可以非常有效地使用索引,但当使用OR时,它实际上必须逐个对其进行评估,而且过程要慢得多,我建议使用两个查询并合并它们。

如果您不使用OR条件,mysql可以非常有效地使用索引,但当您使用OR时,它实际上必须逐个对它们进行评估,而且过程要慢得多,我建议使用两个查询并合并它们。

这是一个打字错误吗
m.id==2
我不是mysql大师,但我从来没有在mysql中看到过双重等式。顺便说一句,
select m.id from member as m,其中m.id=2
select 2
完全相同,或者
使得mysql很难使用索引。单个查询通常只能使用一个索引,因此它必须在
m.id
上的索引或
t2.from\u member\u id
上的索引之间进行选择。无论它选择哪一个,它都必须对另一个进行完全扫描。@dnoeth不完全相同
select 2
总是返回一行,但是select from表要求有一行具有该id。完全相同的是
select 2 from member,其中id=2
@Bohemian:
UNION DISTINCT
是有效语法,当然没有人使用ist,因为它是默认的:)。类似:您可以在标准SQL中编写
selectall
,但这是默认值。这是打字错误吗
m.id==2
我不是mysql大师,但我从来没有在mysql中看到过双重等式。顺便说一句,
select m.id from member as m,其中m.id=2
select 2
完全相同,或者
使得mysql很难使用索引。单个查询通常只能使用一个索引,因此它必须在
m.id
上的索引或
t2.from\u member\u id
上的索引之间进行选择。无论它选择哪一个,它都必须对另一个进行完全扫描。@dnoeth不完全相同
select 2
总是返回一行,但是select from表要求有一行具有该id。完全相同的是
select 2 from member,其中id=2
@Bohemian:
UNION DISTINCT
是有效语法,当然没有人使用ist,因为它是默认的:)。类似:您可以在标准SQL中编写
selectall
,但它仍然是默认值。