提问人:Kingsley Obeng 提问时间:7/18/2023 最后编辑:jarlhKingsley Obeng 更新时间:7/19/2023 访问量:52
嵌套 SQL - 更快?
Nested SQL - faster?
问:
我有一个 SQL 片段,它需要很长时间才能运行,因为它是嵌套的。我只是想知道,是否有办法简化它,让它运行得更快。
下面是 SQL:
select nid
from table_A
where bid in (select bid
from Table_B
where xid in (select xid
from Table_C
where name_l in (select name_l
from accs
where prod like '%arlehen%')))
提前致谢。
答:
1赞
Bogdan Dincescu
7/18/2023
#1
我认为查询可以写成:
select nid
from table_A
where bid in (
select b.bid
from Table_B b
join Table_C c on b.xid=c.xid
join accs on c.name_l=accs.name_l
where accs.prod like '%arlehen%');
新的统计信息,即不是过时的统计信息,可能有助于优化程序选择最佳执行路径。
或者,重写查询的另一种方法是:
with tba as (
select a.*
from accs accs
where a.prod like '%arlehen%'
)
select nid
from table_A
where bid in (
select b.bid
from Table_B b
join Table_C c on b.xid=c.xid
join tba on c.name_l=tba.name_l)
;
评论
2赞
astentx
7/18/2023
但它没有回答为什么它应该提高查询性能,这可能会导致 XY 问题: dbfiddle.uk/PbzO3WIl
0赞
Bogdan Dincescu
7/18/2023
好吧,查询性能可能会提高,也可能不会。有时,即使统计信息未过时,优化程序也可能无法选择最佳执行计划,或者您可能经常在统计信息过时时运行该查询,在这种情况下,以不同的方式编写查询或使用提示可能会有所帮助。如果性能更好,则可以通过运行每个查询来查看。
1赞
astentx
7/18/2023
然而,优化的基础是查询计划。Oracle 的优化器具有非常复杂的查询转换功能(尤其是当实际是视图时),因此我通常仅使用手动添加的提示(用于连接顺序、访问路径)来手动重写此类(有点简单)的查询,以防止表的重新排序不充分table_x
0赞
p3consulting
7/19/2023
#2
您可以尝试将 IN() 替换为 EXISTS(),这可能会降低 I/O 成本 - 当然,要在您的数据集上进行检查:
select nid
from table_A a
where exists (
select 1
from Table_B b
where b.bid = a.bid
and exists (
select 1
from Table_C c
where b.xid = c.xid
and exists (
select 1
from accs ac
where ac.prod like '%arlehen%'
and ac.name_l = c.name_l
)
)
)
;
评论
join
join
prod like '%arlehen%'