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.

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

 

相关文章
|
8月前
|
存储 Oracle 关系型数据库
【YashanDB 知识库】YMP 校验从 yashandb 同步到 oracle 的数据时,字段 timestamp(0) 出现不一致
在YMP校验过程中,从yashandb同步至Oracle的数据出现timestamp(0)字段不一致问题。原因是yashandb的timestamp(x)存储为固定6位小数,而Oracle的timestamp(0)无小数位,同步时会截断yashandb的6位小数,导致数据差异。受影响版本:yashandb 23.2.7.101、YMP 23.3.1.3、YDS联调版本。此问题会导致YMP校验数据内容不一致。
|
9月前
|
Oracle 关系型数据库 Linux
【YashanDB 知识库】通过 dblink 查询 Oracle 数据时报 YAS-07301 异常
客户在使用 YashanDB 通过 yasql 查询 Oracle 数据时,遇到 `YAS-07301 external module timeout` 异常,导致 dblink 功能无法正常使用,影响所有 YashanDB 版本。原因是操作系统资源紧张,无法 fork 新子进程。解决方法包括释放内存、停掉不必要的进程或增大进程数上限。分析发现异常源于 system() 函数调用失败,返回 -1,通常是因为 fork() 失败。未来 YashanDB 将优化日志信息以更好地诊断类似问题。
|
8月前
|
Oracle 关系型数据库 Java
【YashanDB知识库】Flink CDC实时同步Oracle数据到崖山
本文介绍通过Flink CDC实现Oracle数据实时同步至崖山数据库(YashanDB)的方法,支持全量与增量同步,并涵盖新增、修改和删除的DML操作。内容包括环境准备(如JDK、Flink版本等)、Oracle日志归档启用、用户权限配置、增量日志记录设置、元数据迁移、Flink安装与配置、生成Flink SQL文件、Streampark部署,以及创建和启动实时同步任务的具体步骤。适合需要跨数据库实时同步方案的技术人员参考。
【YashanDB知识库】Flink CDC实时同步Oracle数据到崖山
|
8月前
|
存储 Oracle 关系型数据库
【YashanDB 知识库】YMP 校验从 yashandb 同步到 oracle 的数据时,字段 timestamp(0) 出现不一致
【YashanDB 知识库】YMP 校验从 yashandb 同步到 oracle 的数据时,字段 timestamp(0) 出现不一致
|
8月前
|
Oracle 关系型数据库 Linux
【YashanDB知识库】通过dblink查询Oracle数据时报YAS-07301异常
【YashanDB知识库】通过dblink查询Oracle数据时报YAS-07301异常
|
9月前
|
Oracle 关系型数据库 Linux
【YashanDB 知识库】通过 dblink 查询 Oracle 数据时报 YAS-07301 异常
某客户在使用 YashanDB 通过 yasql 查询 Oracle 数据时,遇到 `YAS-07301 external module timeout` 异常,导致 dblink 功能无法正常使用,影响所有版本。问题源于操作系统资源紧张,无法 fork 新子进程。解决方法包括释放内存、停掉不必要的进程或增大进程数上限。分析发现异常原因为系统调用 fork() 失败。经验总结:优化日志记录,提供更多异常信息。
|
8月前
|
存储 Oracle 关系型数据库
【YashanDB知识库】YMP校验从yashandb同步到oracle的数据时,字段timestamp(0)出现不一致
【YashanDB知识库】YMP校验从yashandb同步到oracle的数据时,字段timestamp(0)出现不一致
|
2月前
|
Oracle 关系型数据库 Linux
【赵渝强老师】Oracle数据库配置助手:DBCA
Oracle数据库配置助手(DBCA)是用于创建和配置Oracle数据库的工具,支持图形界面和静默执行模式。本文介绍了使用DBCA在Linux环境下创建数据库的完整步骤,包括选择数据库操作类型、配置存储与网络选项、设置管理密码等,并提供了界面截图与视频讲解,帮助用户快速掌握数据库创建流程。
341 93
|
1月前
|
Oracle 关系型数据库 Linux
【赵渝强老师】使用NetManager创建Oracle数据库的监听器
Oracle NetManager是数据库网络配置工具,用于创建监听器、配置服务命名与网络连接,支持多数据库共享监听,确保客户端与服务器通信顺畅。
176 0
|
4月前
|
存储 Oracle 关系型数据库
服务器数据恢复—光纤存储上oracle数据库数据恢复案例
一台光纤服务器存储上有16块FC硬盘,上层部署了Oracle数据库。服务器存储前面板2个硬盘指示灯显示异常,存储映射到linux操作系统上的卷挂载不上,业务中断。 通过storage manager查看存储状态,发现逻辑卷状态失败。再查看物理磁盘状态,发现其中一块盘报告“警告”,硬盘指示灯显示异常的2块盘报告“失败”。 将当前存储的完整日志状态备份下来,解析备份出来的存储日志并获得了关于逻辑卷结构的部分信息。