探索执行计划中filter的原理


之前写过一篇文章,filter造成的性能问题,开头是这么写的: 

filter这个词总让人很费解,它下一级可以挂 一个子节点,二个子节点,三个子节点...。

挂一个子节点意思过滤,如对全表进行扫描后,按照条件过滤,丢弃不满足条件的数据。

挂二个子节点类似是nest loop。

挂三个子节点类似1和2做nest loop,结果集再与3做nest loop(这个是我推测的)。

为了证明当时的观点,我们下面来做个试验:
filter下挂一个节点:
挂一个节点时,下面的例子可以看到,对表扫描一次,就是对返回的结果集进行过滤,不过有趣的是当条件为假时,不会对表进行扫描。
SQL> select * from emp e where e.hiredate > sysdate - 10000 and e.hiredate < sysdate;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7788 SCOTT ANALYST 7566 19-4月 -87 3000 20
7876 ADAMS CLERK 7788 23-5月 -87 1100 20
SQL> alter session set statistics_level=all;
会话已更改。
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------
SQL_ID 982y5g2z9sn6f, child number 0
-------------------------------------
select * from emp e where e.hiredate > sysdate - 10000 and e.hiredate <
sysdate
Plan hash value: 3896240783
-------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------
|* 1 | FILTER | | 1 | | 2 |00:00:00.01 | 8 |
|* 2 | TABLE ACCESS FULL| EMP | 1 | 2 | 2 |00:00:00.01 | 8 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(SYSDATE@!-10000<SYSDATE@!)
2 - filter(("E"."HIREDATE">SYSDATE@!-10000 AND "E"."HIREDATE"<SYSDATE@!))

SQL> select * from emp e where e.hiredate > sysdate - 10000 and e.hiredate < sysdate - 10000;
未选定行
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
SQL_ID 0pywmdg63gf0m, child number 0
-------------------------------------
select * from emp e where e.hiredate > sysdate - 10000 and e.hiredate
< sysdate - 10000
Plan hash value: 3896240783
---------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time |
---------------------------------------------------------------------------
|* 1 | FILTER | | 1 | | 0 |00:00:00.01 |
|* 2 | TABLE ACCESS FULL| EMP | 0 | 1 | 0 |00:00:00.01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(SYSDATE@!-10000<SYSDATE@!-10000)
2 - filter(("E"."HIREDATE">SYSDATE@!-10000 AND
"E"."HIREDATE"<SYSDATE@!-10000))

更多详情见请继续阅读下一页的精彩内容

  • 1
  • 2
  • 下一页

相关内容