我有一个视图(我们称其为“ main_view”),该视图依赖于同一DB上的另一个视图(view_1)和另一个DB上的另一个视图(可通过db链接view_2访问)。 例如:
create or replace view main_view as
select
...
from (
select
...
from (
select
case when (select xxx from view_1 z where z.id=a.id)='xxx' and ... then ...
when (select yyy from view_2 z where z.id=a.id)='yyy' and ... then ...
else ...
end as c1,
...
from table_1 a, table_2 b, ...
where a.id=b.id and ...
) a
) a
如果以这种方式使用main_view,性能将同样出色:
select * from main_view a where a.id in ('x','y',...)
但是,如果main_view的使用方式类似于以下任何一种,那么性能将非常糟糕(table_n包含1k行):
select a.* from main_view a, table_n b where a.id=b.id;
或
select * from main_view a where a.id in (select z.id from table_n z);
执行计划显示了一对正在执行的表访问存储(在视图中)。
有什么方法可以强制执行计划解决“除main_view以外的所有内容”,然后通过id加入main_view?
作为最后的选择,我尝试使用诸如“有序”,“前导”,“ use_nl”之类的提示,但没有成功(可能是使用了错误的提示)。
select/*+leading(b a)*/ a.* from main_view a, table_n b where a.id=b.id;
select/*+no_merge(b)*/ a.* from main_view a, table_n b where a.id=b.id;
select/*+use_nl(b a)*/ a.* from main_view a, table_n b where a.id=b.id;
select/*+ordered*/ a.* from table_n b, main_view a where a.id=b.id;
有什么主意吗?
执行计划是400多行,实际视图也大约有100多行(并使用“ with”子句,指出这一点可能很重要)。
提前谢谢