21 视图合并(view merge) --优化主题系列

来源:互联网 发布:linux java dlog.path 编辑:程序博客网 时间:2024/06/05 15:05

视图合并(viewmerge)

 

SQL语句中有内联视图(in-lineview,内联视图就是在from后面有select子查询)

或者SQL语句中有用 createview...创建的视图,CBO会将内联视图/视图给展开,进行等价的改写,这个过程就叫做视图合并。如果没有发生视图合并,在执行计划中,我们可以看到VIEW关键字。

 

select * from (select ... from x) a,b where a.id=b.id;a就是内联视图

 

下面举个例子(基于SYSOracle11gR2)

有下面的SQL,其实这个SQL来自于我同事,他请求我优化:

SELECT to_char(wmsys.wm_concat(a.TABLE_NAME))

  FROM user_tables a, dba_objects b

 WHERE a.TABLE_NAME = b.OBJECT_NAME

   AND b.OWNER = 'HBTELEPS'

   ANDB.OBJECT_TYPE = 'TABLE';


user_tables 是不是被展开了??被展开了就叫视图合并

 

现在我们用HINTNO_MERGE禁止USER_TABLES进行视图合并

SELECT /*+ no_merge(a) */ to_char(wmsys.wm_concat(a.TABLE_NAME))

  FROM user_tables a, dba_objects b

 WHERE a.TABLE_NAME = b.OBJECT_NAME

   AND b.OWNER = 'HBTELEPS'

   AND B.OBJECT_TYPE = 'TABLE';


conn scott/tiger

create or replace view emp1 as select ename,job,deptno from empwhere sal>(select avg(sal) from emp);

select ename,job,dname,loc from emp1,dept whereemp1.deptno=dept.deptno;


没有VIEW关键字并且视图的名字也不见了就视图合并了


create or replace view emp1 as select ename,job,deptno from empwhere sal>(select avg(sal) from emp);

select ename,job,dname,loc from emp1,dept whereemp1.deptno=dept.deptno;

select ename, job, dname, loc

  from (select ename, job, deptno

          from emp

         where sal >(select avg(sal) from emp)) emp1,

       dept

 where emp1.deptno = dept.deptno;

 

为什么可以进行视图合并??数学公式的等价转换

我很反对用大量的VIEW用了VIEW会出现性能问题

为什么 CBO要进行VIEWMERGE呢??

CBO认为把视图展开了能更好的进一步优化

 

因为如果不进行视图合并,那么这个视图就会当成一整块,在SQL执行过程中,这个视图就会被当成一个结果集,然后再去和别的表/结果集关联。如果进行了视图合并,那么这个视图就不会当成一整块了,它会被拆散,分开的执行。CBO通常情况下认为视图进行合并之后,性能较高,所以一般情况下都会发生视图合并。但是并不是每次进行了视图合并性能就高,所以我们在进行SQL优化的时候要特别留意视图合并。

 

请特别注意:当子查询/视图里面有

 

1.子查询有ROWNUM

2.子查询有CUBE,ROLLUP

3.子查询有UNION, UNION ALL

4. START WITH ,CONNECT BY

 

优化器可能就不会发生subqueryunnesting/view merge

这个时候就要改写SQL(比如把exists改写为in,notexists改写为notin等等)