内联视图就是from后面再套一个select的子查询,例如:
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;
写sql的时候,我们还会经常的遇到真正的视图(create view …as select)
select …. from view where ……..;
有时候更变态的是,视图里面还套视图,一直给你套n个视图
在oracle ebs/sap/erp系统中经常遇见,要优化这样的sql,必须改代码
其实,视图套视图…..套一堆的视图,这种设计就是垃圾
如果非要这么设计,必须严格测试性能
本文摘自落落优化博客。
==========================================
内联视图:
select * from ( select sal as salary,comm as commission from emp ) x where salary <5000
将取别名的查询作为内联视图,便可以在外部查询中引用其中的别名列。为什么要这么做呢?where 字句是在select 之前进行处理的,这样,在处理求解“问题”查询的where子句之前,Salary和Commission并不存在,要到where子句处理完之后,别名才生效。然后,From子句是在where之前处理的。 所以,将原查询放在FROM子句中,那么,在最外层的WHERE子句之前,以及最外层的WHERE子句“看到”别名之前,那么已经生成了查询结果。这个技巧特别有用。
注意:这个解决方案中的内联视图取名为X。并非所有的数据库都需要内联视图显式给内联视图取别名,但一些数据库是这样子的。所有的DB都接受这种方式。
===========================================
需求:返回所有birthday > 出生于1985年之后的任何客户 的职员名称
上面的SQL语句可以优化为
OCP考题:
内联视图in-line view,就是sql中from后面有select子查询,或者sql中包含有用create view创建的视图,CBO可能会将内联视图或者视图展开,进行相应的等价改写,这种就叫视图合并。直接看一个sql的执行计划
1. user_tables和dba_objects都是静态数据字典,我们来看下sql的执行计划
可以看到id=12这一步有一个view关键字,这一步正好是提取dba_objects视图的数据,然后此表和id=34这一步进行hash join,但hash join的表并不是sql当中的user_tables,而且在整个执行计划当中都找不到这个视图的信息,此视图被展开了。但这种情况我们是不需要展开的
2. 既然不需要展开,我们直接使用hint禁止视图合并
现在可以在执行计划中看到id=3和id=25这两步都是视图,通过hash join连接。
疑问:为什么这里不需要视图合并?
答曰:如果不视图合并,那整个视图就会当成一整块,在sql执行的时候,这个视图就是一个结果集,然后再去和另一个结果集关联。如果合并了的话,那这个视图就会被拆散,视图里面的关联就会分开run,并不是每次视图合并都是高效的。
在执行计划中,如果看到view关键字,说明视图没有展开,也就是视图没有合并,如果本来sql中有内联视图或者视图,但执行计划中没有看到view关键字,那这个sql就进行了视图合并。
此外还需要注意的是,如果sql中的内联视图有聚合等操作,比如rownum,start with,connect by,union,union all,rollup,cube等,这种内联视图就不能展开,因为内联视图被固化了,碰到这种情况就需要注意,如果内联视图中结果集很大,那sql估计就要改写了,因为这个内联视图会最先执行。
综合评级:
想读(1) 在读(0) 已读(0) 品书斋鉴(0) 已有1人发表书评
《Oracle高性能SQL引擎剖析:SQL优化与调优机制详解》第3章查询转换,在本章中,我们将会了解到以下内容:Oracle的逻辑优化技术中,存在哪些启发式查询转换技术,以及它们的具体含义和示例;Oracle的逻辑优化技术中,存在哪些基于代价的查询转换技术,以及它们的具体含义和示例。本节为大家介绍内联视图合并。
AD:2014WOT全球软件技术峰会北京站 课程视频发布
3.1.1.1 内联视图合并
我们以下面两个执行计划为例,简要说明视图合并技术对执行计划优化的影响,见代码清单3-1。
代码清单3-1 内联视图合并
示例分析:上面第一个执行计划是未使用视图合并(通过提示强制)所生成的执行计划。它为视图V_OBJECTS生成了一个子计划(即操作10~12)。该计划从视图查询语句及主查询中获得的谓词条件为("STATUS"=:C AND "OWNER"='SYS' AND "OBJECT_NAME" LIKE :B),并且优化器估算出它会返回571条数据记录。在这种情况下,优化器选择其与另外一个表T_TABLES做哈希关联,估算代价为49。
第二个执行计划使用了视图合并技术,在选择执行计划之前,用视图的依赖表T_OBJECTS替换了视图V_OBJECTS,并且将视图查询中WHERE条件"OWNER"='SYS'与主查询WHERE条件"STATUS"=:C和关联条件"T"."TABLE_NAME"="OBJECT_NAME"合并,最终决定由这些条件访问索引T_OBJECTS_IDX1后与表T_TABLES做嵌套关联,估算代价仅为9。
==============================分类: Oracle
原文地址:Oracle更新的两种方式(merge/update内联视图) 作者:旧梦依稀
Oracle更新的两种方式:一是用merge,二是用update 内联视图
对于Oracle的两表联合更新的场景(有A、B两表,以A.id=B.id关联,根据B表中的记录更新A表中的相应字段),一般有update内联视图和merge两种方式,下面举例介绍:
创建用例表:
CREATE TABLE test1(IDNUMBER(10),NAME VARCHAR2(20));
INSERT INTO test1VALUES(1,'lucy');
INSERT INTO test1VALUES(2,'lily');
CREATE TABLE test2(IDNUMBER(10),NAME VARCHAR2(20));
INSERT INTO test2VALUES(1,'lucy');
INSERT INTO test2VALUES(2,'hanmeimei');
merge方式:
MERGE INTO test1USING test2
ON (test1.id =test2.id)
WHEN MATCHED THENUPDATE
SET test1.name =NVL2(test1.name,test2.name,test1.name);
merge方法是最简洁,效率最高的方式,在大数据量更新时优先使用这种方式。
update内联视图方式:
使用这种方式必须在test2.id上有主键(这里很好理解,必须保证每一个test1.id对应在test2里只有一条记录,如果test2中有多条对应的记录,怎么更新test1?),一般而言这种方式代价比merge方式稍高。
ALTERTABLE test2 ADD CONSTRAINT pk_test2 PRIMARY KEY(ID);
UPDATE (SELECT a.idaid,a.name aname,b.id bid,b.name bname FROM TEST1 a,test2 b WHERE a.id=b.id) t
SETaname = NVL2(aname,bname,aname);
使用并行,加快大量数据更新:
MERGE /*+parallel(test1,4)*/ INTO test1 USING test2
ON (test1.id =test2.id)
WHEN MATCHED THENUPDATE
SET test1.name =NVL2(test1.name,test2.name,test1.name);