explain plan for
select *
from comr_clerk_vou c
where c.vou_type = '11'
and c.sub_vou_type = '0'
and c.vou_status like '%0%';
acc
select * from table(dbms_xplan.display());
---drop index COMR_CLERK_VOU_IDX3;
---create index COMR_CLERK_VOU_IDX3 on COMR_CLERK_VOU (VOU_TYPE,SUB_VOU_TYPE, VOU_STATUS)
Plan hash value: 4001598363
---------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 124 | 14756 | 122 (0)| 00:00:02 |
| 1 | TABLE ACCESS BY INDEX ROWID| COMR_CLERK_VOU | 124 | 14756 | 122 (0)| 00:00:02 |
|* 2 | INDEX RANGE SCAN | COMR_CLERK_VOU_IDX3 | 124 | | 28 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("C"."VOU_TYPE"=11 AND "C"."SUB_VOU_TYPE"=0)
filter("C"."VOU_STATUS" LIKE '%0%' AND "C"."VOU_STATUS" IS NOT NULL)
select count(*)
from comr_clerk_vou c
--268601
select count(*)
from comr_clerk_vou c
where c.vou_type = '11'
and c.sub_vou_type = '0'
--34308
select count(*)
from comr_clerk_vou c
where c.vou_type = '11'
and c.sub_vou_type = '0'
and c.vou_status like '%0%';
--538
ACCESS_PREDICATES VARCHAR2(4000) Predicates used to locate rows in an access structure.
For example, start or stop predicates for an index range scan.
谓词用于在一个访问结构里定位行集,举个例子,开始和停止一个索引扫描
FILTER_PREDICATES VARCHAR2(4000) Predicates used to filter rows before producing them
用于在产生结果前过滤记录
在Oracle 10g里,当我们看到一个SQL的执行计划,有2个感兴趣的地方。
the 'Access predicate' and the 'Filter predicate'.
我们知道依赖于谓词(where 子句),Oracle 优化器选择优化的路径来执行查询
因此'access predicate' 信息高速我们Oracle 优化器如何访问表里的数据。
The 'filter predicate' 告诉我们 什么情况下 Oracle从返回的数据集(通过'access predicate')来过来数据
If you are not making effective use of an index, the index line of an execution plan will highlight the
problem very clearly. The access_predicates column will list the predicates being used to generate the
start and stop keys for the index, but the filter_predicates column will list the predicates that cannot be
used until the leaf blocks have been reached (in other words, the ones that should not be used in the calculation of the effective index selectivity).
如果没有有效的使用索引,执行计划中索引的信息将清晰的显示这个问题。The access_predicates 列将列出被用于声场起始和截止访问index keys,
但是filter_predicates列将列出不能被使用指导所有的叶子快被访问 (换句化说,就是那些在计算有效索引选择率时不应该考虑的谓词。)
create index test_2_idx2 on test_2(end_dt,corp_org)
create index test_2_idx1 on test_2(end_dt)
SQL> select * from test_2 where end_dt > date'2013-05-01' and corp_org='15601'; 2
236734 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 1693794533
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 55903 | 33M| 20844 (1)| 00:04:11 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST_2 | 55903 | 33M| 20844 (1)| 00:04:11 |
|* 2 | INDEX RANGE SCAN | TEST_2_IDX2 | 55903 | | 206 (1)| 00:00:03 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("END_DT">TO_DATE(' 2013-05-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss')
AND "CORP_ORG"='15601' AND "END_DT" IS NOT NULL)
filter("CORP_ORG"='15601')
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
319728 consistent gets
0 physical reads
0 redo size
71706482 bytes sent via SQL*Net to client
174094 bytes received via SQL*Net from client
15784 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
236734 rows processed
select /*+ index(test_2 test_2_idx1)*/* from test_2 where end_dt > date'2013-05-01' and corp_org='15601';
Execution Plan
----------------------------------------------------------
Plan hash value: 4012525493
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5802 | 3518K| 21473 (1)| 00:04:18 |
|* 1 | TABLE ACCESS BY INDEX ROWID| TEST_2 | 5802 | 3518K| 21473 (1)| 00:04:18 |
|* 2 | INDEX RANGE SCAN | TEST_2_IDX1 | 58501 | | 159 (1)| 00:00:02 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("CORP_ORG"='15601')
2 - access("END_DT">TO_DATE(' 2013-05-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
322183 consistent gets
0 physical reads
0 redo size
71706482 bytes sent via SQL*Net to client
174094 bytes received via SQL*Net from client
15784 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
236734 rows processed
结论:索引访问里的filter也不一定就不好,也可能比回表后过滤效率高点。