oracle对于子查询的支持做的很好,oracle optimizer会对inline view进行query transfomation,即视图合并,不过也经常带来意想不到的问题。
下面是一个inline view的merge的例子:

1,  创建临时表

 create table test1 as select * from dba_objects;
create table test2 as select * from dba_objects;

2,  以下查询语句

select *
from test1 t1,
(select owner,
max(object_id) maxo,
min(object_id) mino,
avg(object_id) avgo
from test2
group by owner) t2
where t1.owner = t2.owner
and t1.object_id > t2.avgo;

3,  下面看下语句的执行计划:
  

--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 90420 | 18M| | 1540 (1)| 00:00:19 |
|* 1 | FILTER | | | | | | |
| 2 | HASH GROUP BY | | 90420 | 18M| | 1540 (1)| 00:00:19 |
|* 3 | HASH JOIN | | 90420 | 18M| 3712K| 1535 (1)| 00:00:19 |
| 4 | TABLE ACCESS FULL| TEST2 | 90420 | 2649K| | 246 (1)| 00:00:03 |
| 5 | TABLE ACCESS FULL| TEST1 | 90420 | 16M| | 247 (2)| 00:00:03 |
-------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - filter("T1"."OBJECT_ID">SUM("OBJECT_ID")/COUNT("OBJECT_ID"))
3 - access("T1"."OWNER"="OWNER")

这里,oracle对inline view进行了视图合并,其执行过程是:

  1. 对test2,test1进行hash join。
  2. 对结果进行group by分组
  3. 然后过滤object_id大于均值的记录

看下其执行的情况:

26864 rows selected.
Elapsed: 00:11:53.64
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
2172 consistent gets
1081 physical reads
0 redo size
2304647 bytes sent via SQL*Net to client
20182 bytes received via SQL*Net from client
1792 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
26864 rows processed

两个表的记录数:66957。结果集数:26864。
而整体的运行时间接近12分钟。
下面调整一下查询的执行计划,使用no_merge hint使用优化器不进行查询装换,对inline view不进行合并:

  

select /*+ no_merge(t2)*/*
from test1 t1,
(select owner,
max(object_id) maxo,
min(object_id) mino,
avg(object_id) avgo
from test2
group by owner) t2
where t1.owner = t2.owner
and t1.object_id > t2.avgo; 26864 rows selected.
Elapsed: 00:00:01.47
Execution Plan
----------------------------------------------------------
Plan hash value: 1122024653
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4521 | 1028K| | 1600 (1)| 00:00:20 |
|* 1 | HASH JOIN | | 4521 | 1028K| 6008K| 1600 (1)| 00:00:20 |
| 2 | VIEW | | 90420 | 4944K| | 251 (3)| 00:00:04 |
| 3 | HASH GROUP BY | | 90420 | 2649K| | 251 (3)| 00:00:04 |
| 4 | TABLE ACCESS FULL| TEST2 | 90420 | 2649K| | 246 (1)| 00:00:03 |
| 5 | TABLE ACCESS FULL | TEST1 | 90420 | 15M| | 247 (2)| 00:00:03 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T1"."OWNER"="T2"."OWNER")
filter("T1"."OBJECT_ID">"T2"."AVGO")
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
3934 consistent gets
0 physical reads
0 redo size
1602672 bytes sent via SQL*Net to client
20182 bytes received via SQL*Net from client
1792 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
26864 rows processed

使用no_merge hint,其执行过程是:先对test2先进行group by分组,然后对中间结果集进行hash驱动来join。
对比不同的执行计划,两个执行的时间却相差甚远。

现在打开10046 event,来看一下执行的具体花费的时间和计算的cost:

  

********************************************************************************
select /*+ no_merge(t2)*/*
from test1 t1,
(select owner,
max(object_id) maxo,
min(object_id) mino,
avg(object_id) avgo
from test2
group by owner) t2
where t1.owner = t2.owner
and t1.object_id > t2.avgo
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1792 0.70 0.68 0 3934 0 26864
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 1794 0.70 0.68 0 3934 0 26864
Rows Row Source Operation
------- ---------------------------------------------------
26864 HASH JOIN (cr=3934 pr=0 pw=0 time=569062 us)
121 VIEW (cr=1086 pr=0 pw=0 time=216305 us)
121 HASH GROUP BY (cr=1086 pr=0 pw=0 time=216052 us)
66953 TABLE ACCESS FULL TEST2 (cr=1086 pr=0 pw=0 time=67093 us)
66957 TABLE ACCESS FULL TEST1 (cr=2848 pr=0 pw=0 time=69776 us)
Rows Execution Plan
------- ---------------------------------------------------
0 SELECT STATEMENT MODE: ALL_ROWS
26864 HASH JOIN
121 VIEW
121 HASH (GROUP BY)
66953 TABLE ACCESS (FULL) OF 'TEST2' (TABLE)
66957 TABLE ACCESS (FULL) OF 'TEST1' (TABLE)
********************************************************************************

下面看另外一个merge后的执行情况:

********************************************************************************
select *
from test1 t1,
(select owner,
max(object_id) maxo,
min(object_id) mino,
avg(object_id) avgo
from test2
group by owner) t2
where t1.owner = t2.owner
and t1.object_id > t2.avgo call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1792 530.60 518.52 0 2172 0 26864
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 1794 530.60 518.52 0 2172 0 26864
Rows Row Source Operation
------- ---------------------------------------------------
26864 FILTER (cr=2172 pr=0 pw=0 time=518383093 us)
66957 HASH GROUP BY (cr=2172 pr=0 pw=0 time=518245046 us)
147500423 HASH JOIN (cr=2172 pr=0 pw=0 time=147797490 us)
66953 TABLE ACCESS FULL TEST2 (cr=1086 pr=0 pw=0 time=67029 us)
66957 TABLE ACCESS FULL TEST1 (cr=1086 pr=0 pw=0 time=67029 us) Rows Execution Plan
------- ---------------------------------------------------
0 SELECT STATEMENT MODE: ALL_ROWS
26864 FILTER
66957 HASH (GROUP BY)
147500423 HASH JOIN
66953 TABLE ACCESS (FULL) OF 'TEST2' (TABLE)
66957 TABLE ACCESS (FULL) OF 'TEST1' (TABLE)
********************************************************************************

可以很明显的看出,时间花费在什么地方了。在进行hash group by和filter的过程中花费了大量的时间。
因为test1和test2进行hash join的中间结果有147,500,423条。

  

总结:
无论是inline view的merge还是其它的可选执行计划,最优的那个访问路径一定是具备了以下的条件:

  1. 优先对查询应用过滤性条件,尽可能多的减少中间结果集。
  2. 尽可能的只扫描期望得到的那一部分数据,减少不必要的开销。

oracle查询转换_view merge的更多相关文章

  1. oracle查询转换_inlist转换

    oracle的optimizer会对一些sql语句进行查询转换,比如: 合并视图 子查询非嵌套化 inlist转换 下面讲讲遇到的in list转化优化的案例: create table test( ...

  2. oracle里的查询转换

    oracle里的查询转换的作用 Oracle里的查询转换,有称为查询改写,指oracle在执行目标sql时可能会做等价改写,目的是为了更高效的执行目标sql 在10g及其以后的版本中,oracle会对 ...

  3. 45 个非常有用的 Oracle 查询语句

    ​ 这里我们介绍的是 40+ 个非常有用的 Oracle 查询语句,主要涵盖了日期操作,获取服务器信息,获取执行状态,计算数据库大小等等方面的查询.这些是所有 Oracle 开发者都必备的技能,所以快 ...

  4. 40多个非常有用的Oracle 查询语句

    给大家介绍是40多个非常有用的Oracle 查询语句,主要涵盖了日期操作,获取服务器信息,获取执行状态,计算数据库大小等等方面的查询.这些是所有Oracle 开发者都必备的技能,所以快快收藏吧! 日期 ...

  5. 45个非常有用的 Oracle 查询语句小结

    45个非常有用的 Oracle 查询语句小结 这里我们介绍的是 40+ 个非常有用的 Oracle 查询语句,主要涵盖了日期操作,获取服务器信息,获取执行状态,计算数据库大小等等方面的查询.这些是所有 ...

  6. 45 个非常有用的 Oracle 查询语句(转)

    这里我们介绍的是 40+ 个非常有用的 Oracle 查询语句,主要涵盖了日期操作,获取服务器信息,获取执行状态,计算数据库大小等等方面的查询.这些是所有 Oracle 开发者都必备的技能,所以快快收 ...

  7. Oracle查询速度慢的原因总结

    Oracle查询速度慢的原因总结 查询速度慢的原因很多,常见如下几种:1,没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)2,I/O吞吐量小,形成了瓶颈效应.3,没有创建计算列导致 ...

  8. 40+ 个非常有用的 Oracle 查询语句

    40+ 个非常有用的 Oracle 查询语句,主要涵盖了日期操作,获取服务器信息,获取执行状态,计算数据库大小等等方面的查询.这些是所有 Oracle 开发者都必备的技能,所以快快收藏吧! 日期/时间 ...

  9. 45个很实用的 Oracle 查询语句小结

     这里我们介绍的是 40+ 个很实用的 Oracle 查询语句,主要涵盖了日期操作,获取server信息.获取运行状态.计算数据库大小等等方面的查询. 这些是全部 Oracle 开发人员都必备的技 ...

随机推荐

  1. 开源控件ViewPagerIndicator学习

    导航条指示器.ViewPagerIndicator 地址 https://github.com/JakeWharton/ViewPagerIndicator Style是重用控件的一种技术.类似CSS ...

  2. javascript创建对象和属性的几种方式

    一句话,javascript里面的对象,即是函数.方法. (一)第一种: a.声明对象:var JHSoft = JHSoft || {}; 或者 var JHSoft=new Object(); b ...

  3. ios UIWebview本地加载H5网页

    注意两点 1.拖动文件到工程中选择create folder,文件夹为蓝色  --不要让文件参与编译,而只是让文件加入进来 2.加载方式pathforresorth   oftype   indire ...

  4. == 和 equals()的区别

    package com.liaojianya.chapter1; /** * This program demonstrates the difference between == and equal ...

  5. devenv 命令用法

    devenv是VisualStudio的可执行程序,一般安装在“C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE”下. 这 ...

  6. (转)Libevent(3)— 基础库

    转自:http://name5566.com/4202.html 参考文献列表:http://www.wangafu.net/~nickm/libevent-book/ 此文编写的时候,使用到的 Li ...

  7. HTTP中Get与Post、ViewState 原理

    Http是请求,响应的模型,服务器不会来读取浏览器的网页,只能够得到客户端提交过来的数据当用户点击提交,服务器就知道"提交回来了"(PostBack) Get与Post 设置for ...

  8. 【转】主从同步出现一下错误:Slave_IO_Running: Connecting

    主从同步出现一下错误: Slave_IO_Running: ConnectingSlave_SQL_Running: Yes 解决方法: 导致lave_IO_Running 为connecting 的 ...

  9. 让你的 Node.js 应用跑得更快的 10 个技巧

    Node.js 受益于它的事件驱动和异步的特征,已经很快了.但是,在现代网络中只是快是不行的.如果你打算用 Node.js 开发你的下一个Web 应用的话,那么你就应该无所不用其极,让你的应用更快,异 ...

  10. Python全栈开发-web框架之django

    一:web框架 什么是web框架? Web应用框架(Web application framework)是一种开发框架,用来支持动态网站.网络应用程序及网络服务的开发.这种框架有助于减轻网页开发时共通 ...