Mysql 仅使用一个,其中所有UNION all选择

Mysql 仅使用一个,其中所有UNION all选择,mysql,Mysql,我有这个选择,我想优化它 我想知道我是否可以使用所有这些UNION all只使用一个where,而不是一直重复这个,使mysql扫描表4次而不是1次 select id from sells where user_id in (select fv from favorite where user =?) union all select id from likes where user_id in (select fv from favorite where user =?) union all

我有这个选择,我想优化它

我想知道我是否可以使用所有这些
UNION all
只使用一个
where
,而不是一直重复这个,使mysql扫描表4次而不是1次

select id from sells
where user_id in (select fv from favorite where user =?)
union all
select id from likes
where user_id in (select fv from favorite where user =?)
union all
select id from favorites
where user_id in (select fv from favorite where user =?)
union all
select id from comments
where user_id in (select fv from favorite where user =?)
可能吗?如何更改它?

您可以执行以下操作:

select id,user_id from(
    select id,user_id from sells
    union all
    select id,user_id from likes
    union all
    select id,user_id from favorites
    union all
    select id,user_id from comments
) as t
where user_id in (select fv from favorite where user =?)
select user_id
from (select user_id from sells union all
      select user_id from likes union all
      select user_id from favorites union all
      select user_id from comments
     ) x
where user_id in (select fv from favirote where user = ?);
但是,我不鼓励这样做,因为我的表现很好。有两支安打。首先,子查询被具体化,这会减慢处理速度。更重要的是,子查询没有利用索引,进一步降低了查询速度

假设您有适当的索引(在所有
user\u id
列和
fv
上),那么您的版本可能是最合理的

此外,如果您不希望重复,请使用
union
而不是
union all
。我通常主张
联合所有人
,但这似乎是一种需要重复删除的情况

最有效的方法可能是:

select f.fv
from favorites f
where f.user = ? and
      (exists (select 1 from sells s where s.user_id = f.fv) or
       exists (select 1 from likes l where l.user_id = f.fv) or
       exists (select 1 from favorites f where s.user_id = f.fv) or
       exists (select 1 from comments c where s.user_id = c.fv) 
      );

这可以利用索引,不需要额外的开销。

谢谢!我觉得你的选择比我的快多了,不是吗?哦,所以我应该继续使用我的选择版本?我以为只有一个地方会快得多!多谢各位@利维亚。最快的方法应该是最后一个,但是除了其他表上的索引之外,您还需要在收藏夹(user,fv)上建立索引。谢谢!事实上,这些表可以有每百万行,所以我必须使用最快的一行!再次感谢你!