drop table t1;
drop table t2;
drop table t3;
drop view v_3;create table t1
(f1 integer,
f2 varchar2(10));create table t2
(f1 integer,
f2 varchar2(10));
create index ind_t2 on t2(f2);create table t3
(f1 integer,
f2 varchar2(10));
create index ind_t3 on t3(f2);
create or replace view v_3
as
select f1,f2 from t2
union all
select f1,f2 from t3
-- 如何让下面的查询用到t2,t3上的索引select /*+ordered use_nl(t1,v_3)*/t1.*
from t1,v_3
where t1.f1 = 1
and t1.f2 = v_3.f2
drop table t2;
drop table t3;
drop view v_3;create table t1
(f1 integer,
f2 varchar2(10));create table t2
(f1 integer,
f2 varchar2(10));
create index ind_t2 on t2(f2);create table t3
(f1 integer,
f2 varchar2(10));
create index ind_t3 on t3(f2);
create or replace view v_3
as
select f1,f2 from t2
union all
select f1,f2 from t3
-- 如何让下面的查询用到t2,t3上的索引select /*+ordered use_nl(t1,v_3)*/t1.*
from t1,v_3
where t1.f1 = 1
and t1.f2 = v_3.f2
from t1,v_3
where t1.f1 = 1
and t1.f2 = v_3.f2
----------------------------
你加了上面的hint的话,oracle会倾向于走索引进行nested loop关联的,
除非你的视图中某个表在对应字段上没有索引,这时视图中其他表也将会走全表扫描。比如你drop掉ind_t2后,再看执行计划。
SELECT STATEMENT, GOAL = CHOOSE CPU 耗费=0 IO 耗费=6 耗费=6 基数=1 字节=27
NESTED LOOPS CPU 耗费=0 IO 耗费=6 耗费=6 基数=1 字节=27
TABLE ACCESS FULL 对象名称=T1 对象别名=T1@SEL$1 CPU 耗费=0 IO 耗费=2 耗费=2 基数=1 字节=20
VIEW 对象名称=V_3 对象别名=V_3@SEL$1 CPU 耗费=0 IO 耗费=4 耗费=4 基数=1 字节=7
UNION-ALL
TABLE ACCESS FULL 对象名称=T3 对象别名=T3@SEL$2 CPU 耗费=0 IO 耗费=2 耗费=2 基数=1 字节=7
TABLE ACCESS FULL 对象名称=T2 对象别名=T2@SEL$3 CPU 耗费=0 IO 耗费=2 耗费=2 基数=1 字节=7所以,你必须保证索引中所有原表在关联字段上都要有索引。