昨天晚上帮一位兄弟优化一个ebs的sql。

sql有好几百行。

SQL的样子是select .... from 视图 where ....过滤条件

视图的代码贴出来就不给大家看了,比較长。另外设计保密


那个sql要跑几十秒。

然后那位兄弟把视图代码弄出来。再加过滤条件,0.2秒出结果。 他搞了半天没搞出来。

那位兄弟看运行计划用 plsql 工具 F5 查看。

----记住这句话。谁用F5看运行计划谁就是菜鸟。之后通过查看 explain plan for ...这样的运行计划解决这个问题

该问题相似:

sqlplus / as sysdba

grant dba to scott;

sqlplus scott/tiger

create table test as select * from dba_objects;

SQL> create table test as select * from dba_objects;

表已创建。

create or replace view push_test as select rownum as id,
a.* from test a; SQL> create or replace view push_test as select rownum as id,
2 a.* from test a; 视图已创建。 create index idx_object_id on test(object_id); SQL> set lines 200 pages 200
SQL> set autot trace
SQL> select * from push_test where object_id=2; 运行计划
----------------------------------------------------------
Plan hash value: 677040414 ---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 69219 | 14M| 291 (1)| 00:00:04 |
|* 1 | VIEW | PUSH_TEST | 69219 | 14M| 291 (1)| 00:00:04 |
| 2 | COUNT | | | | | |
| 3 | TABLE ACCESS FULL| TEST | 69219 | 13M| 291 (1)| 00:00:04 |
--------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - filter("OBJECT_ID"=2) Note
-----
- dynamic sampling used for this statement (level=6) 统计信息
----------------------------------------------------------
338 recursive calls
0 db block gets
1323 consistent gets
1033 physical reads
0 redo size
1459 bytes sent via SQL*Net to client
420 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed create or replace view push2_test as select
a.* from test a; SQL> create or replace view push2_test as select
2 a.* from test a; 视图已创建。 SQL> select * from push2_test where object_id=2; 运行计划
----------------------------------------------------------
Plan hash value: 985375477 ---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 207 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 207 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_OBJECT_ID | 1 | | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - access("A"."OBJECT_ID"=2) Note
-----
- dynamic sampling used for this statement (level=6) 统计信息
----------------------------------------------------------
0 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
1403 bytes sent via SQL*Net to client
420 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

意思就是说 在视图 创建的时候 select rownum as ..... 多了这个ROWNUM 导致过滤条件推入不进视图,仅仅能在视图外面过滤。 怎么看在外面过滤呢?

SQL> select * from push_test where object_id=2;

运行计划
----------------------------------------------------------
Plan hash value: 677040414 ---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 69219 | 14M| 291 (1)| 00:00:04 |
|* 1 | VIEW | PUSH_TEST | 69219 | 14M| 291 (1)| 00:00:04 |
| 2 | COUNT | | | | | |
| 3 | TABLE ACCESS FULL| TEST | 69219 | 13M| 291 (1)| 00:00:04 |
--------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 1 - filter("OBJECT_ID"=2) Note
-----
- dynamic sampling used for this statement (level=6) 统计信息
----------------------------------------------------------
338 recursive calls
0 db block gets
1323 consistent gets
1033 physical reads
0 redo size
1459 bytes sent via SQL*Net to client
420 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed

看ID=1 这里 view 前面有* ,*就表示过滤。 * 在view前面,说明过滤是在view上面过滤,而不是在里面过滤的。这个就导致跑得慢了。

由于视图里面有rownum,CBO 必须做一个count操作,这个时候无法进行谓词推入。由于推入了。原始sql语句意义变化。

终于征求那位哥们意见。是否能去掉 视图的 rownum ,假设能去掉。就能优化。假设不能去掉,那sql无法优化。

终于肯定是 干掉了。

记住了。 视图的select后面最好不要包括rownum,否则无法谓词推入。

视图中使用ROWNUM要注意的更多相关文章

  1. ASP.NET Core 中文文档 第四章 MVC(3.8)视图中的依赖注入

    原文:Dependency injection into views 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:孟帅洋(书缘) ASP.NET Core 支持在视图中使用 依赖 ...

  2. YbSoftwareFactory 代码生成插件【二十五】:Razor视图中以全局方式调用后台方法输出页面代码的三种方法

    上一篇介绍了 MVC中实现动态自定义路由 的实现,本篇将介绍Razor视图中以全局方式调用后台方法输出页面代码的三种方法. 框架最新的升级实现了一个页面部件功能,其实就是通过后台方法查询数据库内容,把 ...

  3. mvc Razor 视图中找不到 ViewBag的定义

    在Razor 视图中,我们有时会看到 ViewBag.Title 下会划一个红线,当鼠标放上去的时候会提示这样的一个错误: 找不到编译动态表达式所需的一种或多种类型,是否缺少引用? 但在项目启动运行时 ...

  4. ORACLE DBA_OBJECTS视图中OBJECT_TYPE为LOB的对象查看

    在ORACLE数据库中,DBA_OBJECTS视图中OBJECT_TYPE为LOB的对象是什么东西呢?其实OBJECT_TYPE为LOB就是大对象(LOB),它指那些用来存储大量数据的数据库字段.下面 ...

  5. [转]Oracle中使用Rownum分页详细例子

    原文地址:http://www.jb51.net/article/52272.htm 在MySQL中,我们通常都使用limit来完成数据集获取的分页操作,而在Oracle数据库中,并没有类似limit ...

  6. MVC视图中读取ViewBag传递过来的HashTable表数据

    视图中头部添加 @using System.Collections; 循环读取哈希表数据 <ul id="AccessView" class="sys_spec_t ...

  7. ora-01445:无法从不带保留关键字的表的连接视图中选择ROWID或采样

    系统要创建一个物化试图,用到很多张表,执行的时候报错:   ora-01445:无法从不带保留关键字的表的连接视图中选择ROWID或采样   网上搜了下,有多种原因和解决方法,最终我选择先尝试一下修改 ...

  8. Tips7:Unity中 Scene视图 和 Game视图 中 视角(Camera)的控制

    选中你要改变的相机,然后点击GameObject-->Align With View 选项(快捷键Ctrl+Shift+F)使相机视角和当前Sence视图中一样 通过这样可以控制在Game视图( ...

  9. MVC,如何在视图中声明方法,调用方法?

    <div> <!--在视图中申明方法,此方法的类型已经固定为HelperResult--> @helper ShowHello(string s) { <div> ...

随机推荐

  1. 41.AngularJS 服务(Service)

    转自:https://www.cnblogs.com/best/tag/Angular/ 什么是服务? 在 AngularJS 中,服务是一个函数或对象,可在你的 AngularJS 应用中使用. A ...

  2. [ xml ] [ log4j2 ] No grammar constraints (DTD or XML Schema) referenced in the document.

    <!DOCTYPE xml> http://rx1226.pixnet.net/blog/post/321584550

  3. BootStrap--panel面板

    1 <div class="panel panel-default"> <div class="panel-body"> 这是一个基本的 ...

  4. Windows10显示桌面我的电脑等图标

    1.桌面右键,选择最后一项:个性化 2. 选择:主题 --> 桌面图标设置 3. 将需要显示的图标勾上就可以啦.

  5. C#线程安全打开/保存文件对话框

    在多线程单元模式(MTA)中为应用程序使用.NET OpenFileDialog和SaveFileDialog 下载FileDialogsThreadAppartmentSafe_v1.zip 如果您 ...

  6. [洛谷P1726][codevs1332]上白泽慧音

    题目大意:求一个有向图的最大强连通分量中点的个数,并输出这些点(字典序最小). 解题思路:裸的强连通分量. 数据小,求完强连通分量后排序+vector大小比较即可(vector有小于运算符). C++ ...

  7. 转移顺序的艺术 luogu4394 + lougu2966 + luogu3537

    lougu4394: N个政党要组成一个联合内阁,每个党都有自己的席位数. 现在希望你找出一种方案,你选中的党的席位数要大于总数的一半,并且联合内阁的席位数越多越好. 对于一个联合内阁,如果某个政党退 ...

  8. 第五讲 自对偶的Yang-Mills方程及Polyakov和t'Hooft解

    $\newcommand{\R}{\mathbb{R}}$以下我们考虑的是$\R^4$或者$S^4$上的Yang-Mills泛函,它们是共形不变的. 一.自对偶和反自对偶 我们寻找$\R^4$或$S^ ...

  9. jquery中$.get()提交和$.post()提交有区别

    jquery中$.get()提交和$.post()提交有区别吗? 相同点:都是异步请求的方式来获取服务端的数据: 异同点: 1.请求方式不同:$.get() 方法使用GET方法来进行异步请求的.$.p ...

  10. [Recompose] Stream a React Component from an Ajax Request with RxJS

    Loading data using RxJS is simple using Observable.ajax. This lesson shows you how to take the ajax ...