分布式查询可能一条SQL语句中有不同远程库的表,优化分布式查询要达到3点效果:
1.访问同一个远程库的次数要尽量少,也就是同一远程库的对象应该尽量转为一条SQL运算,一次运算,运算后将结果返回给本地库
2.从远程库上返回到本地库的结果要尽量少,只访问远程对象需要的字段
3.远程库上执行的语句的计划以及远程库返回的结果与本地可以联合查询的计划应该高效优化分布式查询需要从以上3个方面着手。
---->
--使用HINT,特别是driving_site HINT
/*+driving_site(table_name)*/ : table_name 一般是大表!
对远程表可以使用hint,比如parallel,use_nl,use_hash,FULL等。
driving_site hint能够指定执行计划在远程还是本地做,比如下面使用driving_site(remot_tablename),那么原来的远程表就相当于本地表,本地表要传输给remote库,主计划在remote库上执行。默认是本地驱动的。
使用driving_site(目标表),特别是本地小结果集,远程大结果集的时候,总体结果集较小,希望计划在远程驱动,这样远程执行完毕,将结果集传输到本地,这样避免大结果集的传输。
driving_site hint注意点:
driving_site对dml无效,dml以目标表所在库驱动SQL计划。但是其他的hint还是有效的。如果想用driving_site,可以使用plsql中for循环的dml操作。
create or replace procedure p_into_link as
begin
execute immediate 'truncate table t_shaw';
execute immediate 'alter session set workarea_size_policy=manual';
execute immediate 'alter session set sort_area_size=50000000';
insert /*+append nologging parallel*/ into t_shaw
--select * from t_zhong@dborcl;
select /*+driving_site(t_zhong) parallel*/ * from t_zhong@dborcl;
commit; ----这里driving_site指定是失效的 后面那个并行可以用
end p_into_link;
reference http://www.itpub.net/thread-1786077-1-1.html
http://blog.chinaunix.net/丁俊 新炬网络
--使用insert into导致driving_site hint失效,怎么办?
----使用存储过程for循环插入,需要查询的结果中没有lob字段
create or replace procedure p_insert as
begin
for i in (select /*+driving_site(t_zhong)*/ * from t_zhong@dborcl
where seq > (select max(seq) from t_test1)) loop
insert into t_test1 values (i.info, i.seq, i.vseq);
end loop;
end;
----或如下:
create or replace procedure p_insert as
begin
DECLARE
CURSOR remote_insert IS(
select /*+driving_site(t_zhong)*/ * from t_zhong@dborcl
where seq > (select max(seq) from t_test1));
BEGIN
FOR i IN remote_insert LOOP
insert into t_test1 values (i.info, i.seq, i.vseq);
END loop;
end;
END;
Reference http://blog.csdn.net/stevendbaguo/
http://docs.oracle.com/cd/E11882_01/
Reference 以下来自: http://mp.weixin.qq.com/
概念
日常工作中经常会用到分布式数据库查询,即通过DBLINK同时查询本地表和远程表。分布式查询一般有两种处理方式:一种将远程表数据取回本地,然后和本地表关联查询,获取最终结果,另一种将本地表数据传到远程和远程表关联查询后,再将关联结果取回。前一种处理方式可理解为只有一次网络传输操作比后一种少,也就作为了数据库的默认处理方式;
driving_site提示能够指定执行计划在远程还是本地做,使用driving_site,特别是本地小结果集,远程大结果集,最终结果集较小时,希望计划在远程驱动,这样远程执行完毕,将结果集传输到本地,避免了大结果集的网络传输,从而达到整体优化的效果。
但是注意对于DML,DDL语句,driving_site提示是失效的,会自动被ORACLE忽略掉,此时将以目标表所在库为主计划驱动,相当于driving_site(目标表库);DML,DDL中如果是对本地表做DML,主计划总是在本地做,会将远程数据拉到本地,相当于driving_site(本地表);如果是对远程表做DML,主计划总是在远程做,会将本地数据送到远程,相当于自动driving_site(远程表)。
为实现DML优化效果,避免大数据量的网络传输,下面调整为在远程库(BSSDB)上将插入UDT_SALS_GL表的语句创建成视图,然后再在本地库上读取此视图来最终完成插入功能。
远程库BSSDB上,创建视图:
SQL> create view vw_udt_sals_gl as
2 select t.jyzh as hkzh , a.actactno as dkzh , 'PLAF' as cpm , a.ACTDRTBA as dkye , a.actratvl / 100 as llz
3 from (select trim(t.actactno) as actactno,
4 trim(t.actdrtba) as actdrtba,
5 trim(t.actratvl) as actratvl,
6 trim(a.actretac) as actretac,
7 trim(t.actdlttm) as actdlttm
8 from borms t
9 inner join boiss a on a.actactno = t.actactno and a.jgh = t.jgh) a
10 inner join udt_fnpt_qyxx@cssdb t on '0' || substr(t.jyzh, 1, 16) = a.ACTRETAC
11 where a.actdrtba > 0
12 and t.cplx = 'SALS';
View created.
本地库CSSDB,改为读取远程视图完成插入,效果同添加了driving_site:
SQL> insert into udt_sals_gl
2 select * from vw_udt_sals_gl@bssdb;
已创建10395行。
已用时间: 00: 00: 00.64
要注意看清执行计划中operation为remote处对应的name是什么,是本地表则表示本地的表被推送到远程数据库上;此外,由于实验环境为测试环境,真实生产环境上数据量要大很多,网络开销也会更大,导致的性能差异只会更明显。
1. driving_site优化,以减少总体的网络传输数据量为目标;
2. 当driving_site驱动的对象嵌套在视图中时,可通过driving_site(V.T)方式来指定,其中V表示视图别名或名称,T表示视图里表的别名或名称;
3. DML,DDL语句中driving_site提示无效,总是会以目标表所在的库为主计划驱动,此时可以通过视图转换来达到优化目的。