PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
EXPLAINED SQL STATEMENT:
------------------------
SELECT count(pad) FROM t WHERE id < :id
Plan hash value: 2966233522
-----------------------------------
| Id | Operation | Name |
-----------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SORT AGGREGATE | |
| 2 | TABLE ACCESS FULL| T |
6:绑定变量变为10,其实这个时候应该走index 好。但是由于绑定偷窥。cbo傻了,仍然走全表扫描
[sql]
SQL> EXECUTE :id := 10;
PL/SQL procedure successfully completed.
SQL> SELECT count(pad) FROM t WHERE id < :id;
COUNT(PAD)
----------
9
SQL> SELECT * FROM table(dbms_xplan.display_cursor(NULL, NULL, 'basic'));
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
EXPLAINED SQL STATEMENT:
------------------------
SELECT count(pad) FROM t WHERE id < :id
Plan hash value: 2966233522
-----------------------------------
| Id | Operation | Name |
-----------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SORT AGGREGATE | |
| 2 | TABLE ACCESS FULL| T |
7:第2次在执行这个语句。注意这个时候的绑定变量带人的值仍然是10,
[sql]
SQL> SELECT count(pad) FROM t WHERE id < :id;
COUNT(PAD)
----------
9
SQL> SELECT * FROM table(dbms_xplan.display_cursor(NULL, NULL, 'basic'));
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
EXPLAINED SQL STATEMENT:
------------------------
SELECT count(pad) FROM t WHERE id < :id
Plan hash value: 4270555908
---------------------------------------------
| Id | Operation | Name |
---------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SORT AGGREGATE | |
| 2 | TABLE ACCESS BY INDEX ROWID| T |
| 3 | INDEX RANGE SCAN | T_PK |
---------------------------------------------
发现了执行计划改变为走索引。
这就是11g的新特性。
总结 :
ACS是指Oracle在不同cursor sharing技术之间进行自主选择。Oracle支持两种cursor sharing技术:
传统的PCST(Previous Cursor Sharing Technique),在硬解析时生成cursor,后续的semantically equivalent sql总是共享这个cursor,不会重复硬解析。
Oracle11g新引入的ECST(Extended Cursor Sharing Technique),根据不同semantically equivalent sql的selectivity等因素,Oracle可能会硬解析和创建新的cursor。
采用ECST后,Oracle在解析sql语句时就根据绑定变量值来评估谓词的selectivity。如果在软解析阶段找到可用的child cursor,
并且这个child cursor的selectivity范围涵盖了先前评估得到的selectivity,那就共享这个cursor,否则就新建执行计划,也就是硬解析。
(child cursor的selectivity范围保存在V$SQL_CS_SELECTIVITY视图中)。
硬解析得到新的执行计划后再和原来的child cursor的执行计划做比较,如果两者相差很大,就产生新的child cursor,
并记录selectivity范围(例如selectivity是0.01,那么范围就是0.009~0.011。如果是0.2,那么范围可能就是0.15~0.25)。
如果执行计划相同,那就共享原来的cursor,并且调整这个cursor的selectivity范围。
Oracle缺省采用PCST,因为它代价低,并且也足够好。ECST只对数据倾斜得很厉害的表有效。而ACS就是判断在什么情况下由PCST转为ECST。
在用相同的child cursor执行多次semantically equivalent