只使用一个UNION ALL选择的地方

时间:2015-10-10 12:35:43

标签: mysql mysqli

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

我想知道我是否可以使用所有这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 =?)

有可能吗?我怎么能改变它?

2 个答案:

答案 0 :(得分:2)

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 =?)

答案 1 :(得分:0)

你可以这样做:

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_id列和fv上)。

此外,如果您不想重复,请使用union代替union all。我通常提倡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) 
      );

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