oracle_执行计划_谓词信息和数据获取(access and filter区别) (转)
These two terms in the Predicate Information section indicate when the data source is reduced. Simply, access means only retrieve those records meeting the condition and ignore others. Filter means *after* you already got the data, go through them all and keep those meeting the condition and throw away the others.
access: 直接获取那些满足条件的数据,抛弃其他不满足的数据
filter: 你已经有了一些数据,对这些已经有的数据应用filter,得到满足filter的数据。
http://www.itpub.net/forum.php?mod=viewthread&tid=1766289
一:简要说明
在查看执行计划的信息中,经常会看到两个谓词filter和access,它们的区别是什么,理解了这两个词对我们解读Oracle的执行计划信息会有所帮助。
简单说,执行计划如果显示是access,就表示这个谓词条件的值将会影响数据的访问路径(表还是索引),而filter表示谓词条件的值并不会影响数据访问路径,只起到过滤的作用。
二:举例说明
SQL> create table zhou_t (x int , y int );
表已创建。
SQL> set autotrace trace exp;
SQL> select /*+rule*/ * from zhou_t where x=5;
执行计划
----------------------------------------------------------
Plan hash value: 1395150869
------------------------------------
| Id | Operation | Name |
------------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | TABLE ACCESS FULL| ZHOU_T |
------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("X"=5)
Note
-----
- rule based optimizer used (consider using cbo)
因为表zhou_t没有创建索引,执行计划没有选择数据访问路径的余地,谓词条件在这里只是起到数据过滤的作用,所以使用了filter
如果在表上创建了索引呢?
SQL> create index zhou_t_idx on zhou_t(x,y);
索引已创建。
SQL> select /*+rule*/ * from zhou_t where x=5;
执行计划
----------------------------------------------------------
Plan hash value: 42197324
---------------------------------------
| Id | Operation | Name |
---------------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | INDEX RANGE SCAN| ZHOU_T_IDX |
---------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("X"=5)
Note
-----
- rule based optimizer used (consider using cbo)
从上面可以看到,谓词条件影响到数据访问的路径------选择了索引,所以用access
http://zuoren110.blog.163.com/blog/static/617563201201331427675/
SQL> create table t
2 as select rownum r,object_name
3 from dba_objects
4 /
Table created.
SQL> create index t_idx on t(r);
Index created.
SQL> execute dbms_stats.gather_table_stats(user,'t',cascade=>true)
PL/SQL procedure successfully completed.
SQL> set autotrace traceonly explain
SQL> select * from t
2 where r = 10000;
Execution Plan
----------------------------------------------------------
Plan hash value: 470836197
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 30 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 30 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T_IDX | 1 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("R"=10000)
使用的谓词是access ,访问的是索引,然后通过rowid 直接取出select结果。
SQL> select * from t
2 where r > 10000 and r < 50000
3 /
Execution Plan
----------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 40001 | 1171K| 88 (2)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| T | 40001 | 1171K| 88 (2)| 00:00:02 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("R"<50000 AND "R">10000)
使用的谓词是filter 使用的是全表扫描,过滤掉不需要的行。
SQL> select r from t
2 where r > 10000
3 /
Execution Plan
----------------------------------------------------------
Plan hash value: 3163761342
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 55631 | 271K| 42 (3)| 00:00:01 |
|* 1 | INDEX FAST FULL SCAN| T_IDX | 55631 | 271K| 42 (3)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("R">10000)
这里的执行计划,就有点意思了,使用的是索引扫描(index fast full scan),
但是没有通过access 指出。可见oracle 决定使用索引扫描,并不一定要通过
access 来告诉我们。在这里r 可以完全通过读取索引来获得所需要的列值,并且
需要检索索引中的大部分key,所以oracle 决定使用index fast full scan,这种
访问索引的方式会通过multiblocks read 方式读取索引的 bocks,返回的结果集
是未经排序的,并且因为读取了所以的index blocks ,所以需要对index blocks
中的index keys 进行过滤。
SQL> create table emp
2 as select employee_id,first_name,last_name
3 from hr.employees;
Table created.
SQL> create index emp_idx on emp(employee_id,last_name);
Index created.
SQL> exec dbms_stats.gather_table_stats(user,'emp',cascade=>true)
PL/SQL procedure successfully completed.
SQL> select employee_id,last_name
2 from emp
3 where employee_id < 200 and last_name = 'King'
4 /
Execution Plan
----------------------------------------------------------
Plan hash value: 3087982339
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 24 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| EMP_IDX | 2 | 24 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("LAST_NAME"='King' AND "EMPLOYEE_ID"<200)
filter("LAST_NAME"='King')
我上面这个例子也比较有意思,我们在前面创建了一个复合索引,并且在where 子句中
使用了索引中的列。oracle 会根据where 条件通过访问复合索引中的列是否满足employee_id < 200
如果满足再根据条件filter 过滤出last_name = 'King' 的index Key。
小结:通过上面的列子,虽然例子不是很经典,但是我觉得已经可以说明。
1、如果oracle 决定使用 index 来获得结果集,不需要使用access 谓词告诉我们,我(oracle)使用了index.
2、通过index 访问数据,也有可能需要用到filter 的。
http://blog.csdn.net/kkdelta/article/details/7938653
oracle_执行计划_谓词信息和数据获取(access and filter区别) (转)的更多相关文章
- SQL Server 执行计划利用统计信息对数据行的预估原理二(为什么复合索引列顺序会影响到执行计划对数据行的预估)
本文出处:http://www.cnblogs.com/wy123/p/6008477.html 关于统计信息对数据行数做预估,之前写过对非相关列(单独或者单独的索引列)进行预估时候的算法,参考这里. ...
- Oracle执行计划与统计信息的一些总结
[日期:2011-08-05]来源:Linux社区 作者:wangshengfeng1986211[字体:大 中 小] 2010-07-01 15:03 1.SET AUTOTRACE ON EXP ...
- sqlplus中显示sql执行计划和统计信息
31 ,32 , 33 ,34 keywords : oracle storage structure 最详细讲解: 1:doc 1 logical storage structure 2 ...
- 为准确生成执行计划更新统计信息-analyze与dbms_stats
如果我们想让CBO利用合理利用数据的统计信息,正确判断执行任何SQL查询时的最快途径,需要及时的使用analyze命令或者dbms_stats重新统计数据的统计信息. 例如索引跳跃式扫描(INDEX ...
- SQL Server 执行计划利用统计信息对数据行的预估原理以及SQL Server 2014中预估策略的改变
前提 本文仅讨论SQL Server查询时, 对于非复合统计信息,也即每个字段的统计信息只包含当前列的数据分布的情况下, 在用多个字段进行组合查询的时候,如何根据统计信息去预估行数的. 利用不同字段 ...
- 当执行计划中出现BITMAP CONVERSION TO ROWIDS关键字时,需要注意了。
前言 前些天优化了一些耗费buffers较多的SQL,但系统CPU降低的效果不明显,于是又拉了awr报告,查看了SQL ordered by Gets排名前列的SQL. 分析 SQL代码: selec ...
- MySQL统计信息以及执行计划预估方式初探
数据库中的统计信息在不同(精确)程度上描述了表中数据的分布情况,执行计划通过统计信息获取符合查询条件的数据大小(行数),来指导执行计划的生成.在以Oracle和SQLServer为代表的商业数据库,和 ...
- sql-查看执行计划的方法
sql执行计划:把SQL语句拆分为每个的操作步骤组合,按照一定的顺序执行得出结果,查看并看懂执行计划是调优的关键步骤 查看执行计划的方法 DBMS_XPLAN包 sql*plus AUTO trace ...
- [z]Oracle性能优化-读懂执行计划
http://blog.csdn.net/lifetragedy/article/details/51320192 Oracle的执行计划 得到执行计划的方式 Autotrace例子 ...
随机推荐
- Android 省市县 三级联动(android-wheel的使用)[转]
转载:http://blog.csdn.net/lmj623565791/article/details/23382805 今天没事跟群里面侃大山,有个哥们说道Android Wheel这个控件,以为 ...
- redis+keeplived分布式缓存
redis(三)redis+Keepalived主从热备秒级切换 博客分类: 分布式缓存Redis redis高可用Keepalived 一 简介 安装使用centos 5.10 Master 19 ...
- CSU1661: Query Mutiple
Description One day,Little-Y saw many numbers standing in a row. A question suddenly appeared in her ...
- [转] Linux文件系统之hard link&symbol link
这个图很清楚的表示出硬链接和软链接的方式. 1.硬链接: 基本定义:硬链接是有着相同inode号的仅文件名不同的文件(该文件名包含路径信息). 理解:如图,hard link和原始file通过同一个i ...
- Oracle 存储过程(2)
http://www.cnblogs.com/chinafine/archive/2010/07/12/1776102.html http://blog.itpub.net/29485627/view ...
- 转载:C# 之泛型详解
本文原地址:http://www.blogjava.net/Jack2007/archive/2008/05/05/198566.html.感谢博主分享! 什么是泛型 我们在编写程序时,经常遇到两个模 ...
- 移动页面缩放方法之(一)控制meta法
<!DOCTYPE HTML> <html lang="zh-cn"> <head> <meta http-equiv="Con ...
- Wpf控件ListBox使用实例2
2.Xaml绑定选择结果 <StackPanel Orientation="Vertical"> <TextBlock Margin="10,10,10 ...
- 【USACO 3.2.1】阶乘
[描述] N的阶乘写作N!表示小于等于N的所有正整数的乘积.阶乘会很快的变大,如13!就必须用32位整数类型来存储,70!即使用浮点数也存不下了.你的任务是找到阶乘最后面的非零位.举个例子,5!=1* ...
- Linux下python3与python3的多版本共存
python3已经出来有些许时候了,python3相比python2进行了大量的改进,包括语法,新的功能,还有优化.虽然很多库已经同时支持 python2和python3了,但是有些库仍然没有很好的支 ...