一条关于DBLINK的ORACLE SQL优化
最近发现报表系统上有一存储过程越来越慢,在数据库中查询后,发现有以下条SQL:
运行时间>1h
执行计划如下:


记得该SQL我是在一年前进行优化过,现在随着数据量增长,以前的优化方法(添加hint)看来是不适合了。。
对SQL进行分析
在以上执行计划中可以看出该SQL,查询的都是远程表。
所以可以改写成以下形式,然后在远程库直接执行。

执行计划如下:

执行计划中有filter关键字且有两个子级,一般来说是很耗费性能。
如果不进行改写,根据自己的经验,最有效的方式就是在执行计划中谓词信息里找出有绑定变量的字段并建立索引。
所以建立如下索引:

执行SQL,10s内能返回全部结果。
但是,
在报表库上运行时,发现SQL的性能还是没改善。

重新查看执行计划:

此sql运行时,采用多个dblink访问远程库。
查看dblink的元数据:
发现两个DBLINK都是访问AUTOCLAIM用户下的表。
这种方式很容易造成sql不能走正确执行计划,所以可以把sql中的dblink改写成同一个。
再次执行,10s内能返回全部结果。
执行计划如下:

该SQL到此就优化完成了。
构建测试案例
在db2上
创建表T1与T2
create table t1 select * from dba_objects;
create table t2 select * from dba_segments;
插入数据:
insert into t1 as select * from t1;
insert into t1 as select * from t1;
insert into t1 as select * from t1;
insert into t1 as select * from t1;
insert into t1 as select * from t1;
commit;
insert into t2 as select * from t2;
insert into t2 as select * from t2;
insert into t2 as select * from t2;
insert into t2 as select * from t2;
commit;
在db1上
创建DBLINK:
create public database link dblink1 connect to wanbin identified by wanbin using 'db2';
create public database link dblink2 connect to wanbin identified by wanbin using 'db2';
执行sql进行查询
select distinct a.owner, a.object_id, b.segment_name, b.bytes
from t1@dblink1 a
left join t2@dblink1 b
on a.object_name = b.segment_name
where exists
(select t1.owner from t1@dblink2 t1 where t1.owner=a.owner and rownum>=1)
and a.object_type in (select t2.segment_type
from t2@dblink2 t2
where t2.bytes > 1024);
测试的时候,可以用10053进行跟踪分析。。




