Oracle版本:12.2
操作系统:Oracle Linux 7.4
SQL语句如下:
因为应用系统是很多年的系统,开发反馈基本不让动代码的, zb_1ddb, xb_2ddb 都是单表的视图;
select zb_1ddb.jm,
sum(zb_1ddb.zb_1005) + sum(zb_1ddb.zb_1009) as GTYS1001,
sum(zb_1ddb.zb_1006) as GTYS1002,
sum(zb_1ddb.zb_1007) as GTYS1003,
sum(XB_2DDB.XB_2003) as GTYS1005,
sum(zb_1ddb.zb_1002) as GTYS1006
from zb_1ddb, xb_2ddb
where 1 = 1
and zb_1ddb.ymd >= to_date('2020-04-01', 'yyyy-mm-dd')
and zb_1ddb.ymd < to_date('2020-05-01', 'yyyy-mm-dd')
and xb_2ddb.ymd >= to_date('2020-04-01', 'yyyy-mm-dd')
and xb_2ddb.ymd < to_date('2020-05-01', 'yyyy-mm-dd')
and zb_1ddb.jm = xb_2ddb.jm
and zb_1ddb.ymd = xb_2ddb.ymd
and zb_1ddb.jm <> '+ '
group by zb_1ddb.jm;
拿到语句后,看了看语句没有什么特别之处,无非就是两个结果集关联过滤,但结果只返回16行数据,但消耗38秒,看如下执行计划:

看到执行计划发现,被驱动表关联列也是走的索引 INDEX_XB2_003 但扫描了570次,很明显执行计划有问题,这两个视图对应的基表都30M左右。
最简单的最粗暴的方式改变它的执行计划:
select /*+ use_hash(zb_1ddb,xb_2ddb) */
zb_1ddb.jm,
sum(zb_1ddb.zb_1005) + sum(zb_1ddb.zb_1009) as GTYS1001,
sum(zb_1ddb.zb_1006) as GTYS1002,
sum(zb_1ddb.zb_1007) as GTYS1003,
sum(XB_2DDB.XB_2003) as GTYS1005,
sum(zb_1ddb.zb_1002) as GTYS1006
from zb_1ddb, xb_2ddb
where 1 = 1
and zb_1ddb.ymd >= to_date('2020-04-01', 'yyyy-mm-dd')
and zb_1ddb.ymd < to_date('2020-05-01', 'yyyy-mm-dd')
and xb_2ddb.ymd >= to_date('2020-04-01', 'yyyy-mm-dd')
and xb_2ddb.ymd < to_date('2020-05-01', 'yyyy-mm-dd')
and zb_1ddb.jm = xb_2ddb.jm
and zb_1ddb.ymd = xb_2ddb.ymd
and zb_1ddb.jm <> '+ '
group by zb_1ddb.jm;
居然秒出了。。再次查看执行计划

建议:如果能在修改视图重构的情况下尽量修改,少用HINT,尽量让Oracle 自己判断,我这也是没办法的办法了。。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/30327022/viewspace-2691103/ ,如需转载,请注明出处,否则将追究法律责任。