包含联合的选择的优化

问题描述 投票:0回答:2

我很容易选择:

define account_id = 7
select * from A where ACCOUNT_ID = &account_id
UNION
select * from B where ACCOUNT_ID = &account_id;

我想让account_id作为另一个选择的输入,我这样做是这样的:

select * from A where ACCOUNT_ID in(select accound_id from ACCOUNTS where EMAIL like '[email protected]') -- id 7 returned
UNION
select * from B where ACCOUNT_ID in(select accound_id from ACCOUNTS where EMAIL like '[email protected]')

如何优化这种方法只调用一次select accound_id from ACCOUNTS where EMAIL like '[email protected]'

sql oracle union query-performance
2个回答
1
投票

我的第一个问题是union是否可以用union all代替。因此,我的第一个尝试是使用existsunion all

select a.*
from a
where exists (select 1
              from accounts aa
              where aa.account_id = a.account_id and
                    aa.email = '[email protected]'
             )
union all
select b.*
from b
where exists (select 1
              from accounts aa
              where aa.account_id = b.account_id and
                    aa.email = '[email protected]'
             );

对于此结构,您想要accounts(account_id, email)上的索引。 exists只是在索引中查找值。这确实需要扫描ab

如果查询返回的是少数几行,并且您想删除重复项,则单击union并替换union all。如果返回大量行-并且每个表中都没有重复项,并且有一种简单的方法来识别重复项-那么您可以改为:

with cte_a as (
      select a.*
      from a
      where exists (select 1
                    from accounts aa
                    where aa.account_id = a.account_id and
                          aa.email = '[email protected]'
                   )
       )
select cte_a.*
from ctea_a
union all
select b.*
from b
where exists (select 1
              from accounts aa
              where aa.account_id = b.account_id and
                    aa.email = '[email protected]'
             ) and
      not exists (select 1
                  from cte_a
                  where cte_a.? = b.?  -- whatever is needed to identify duplicates
                 );

1
投票

这是WITH派上用场的地方>>

WITH ids AS (select account_id from ACCOUNTS where EMAIL like '[email protected]')
select * from A where ACCOUNT_ID in ids
UNION ALL
select * from B where ACCOUNT_ID in ids;

我也将其更改为UNION ALL,因为它快得多。

© www.soinside.com 2019 - 2024. All rights reserved.