之前我一直以为同样一个sql在运行过程中,其执行计划是不会改变的,今天通过一个实验证明了执行中sql的执行计划也是会动态变化的。。。。。
用一个循环让一个sql反复被执行
DECLARE
a VARCHAR2(2000);
BEGIN
FOR i IN 1..500000 LOOP
SELECT b.object_name INTO a FROM b WHERE b.object_id=i;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
此时b表的object_id是没有建索引的,通过session查sql_id,再通过 sql_id查看其执行计划,发现是全表扫描
1 SQL_ID 5xfs1quypwtyv, child number 0
2 -------------------------------------
3 SELECT B.OBJECT_NAME FROM B WHERE B.OBJECT_ID=:B1
4
5 Plan hash value: 1911541843
6
7 --------------------------------------------------------------------------
8 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
9 --------------------------------------------------------------------------
10 | 0 | SELECT STATEMENT | | | | 3 (100)| |
11 |* 1 | TABLE ACCESS FULL| B | 1 | 79 | 3 (0)| 00:00:01 |
12 --------------------------------------------------------------------------
13
14 Predicate Information (identified by operation id):
15 ---------------------------------------------------
16
17 1 - filter("B"."OBJECT_ID"=:B1)
此时循环还在执行,我马上在 object_id上建个索引
create index AA on B (OBJECT_ID)
tablespace USERS
再通过上面的方法查看执行计划,发现此时执行计划已经改变,但sql_id并没有变化
1 SQL_ID 5xfs1quypwtyv, child number 0
2 -------------------------------------
3 SELECT B.OBJECT_NAME FROM B WHERE B.OBJECT_ID=:B1
4
5 Plan hash value: 3427984464
6
7 ------------------------------------------------------------------------------------
8 | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
9 ------------------------------------------------------------------------------------
10 | 0 | SELECT STATEMENT | | | | 1 (100)| |
11 | 1 | TABLE ACCESS BY INDEX ROWID| B | 1 | 79 | 1 (0)| 00:00:01 |
12 |* 2 | INDEX RANGE SCAN | AA | 1 | | 1 (0)| 00:00:01 |
13 ------------------------------------------------------------------------------------
14
15 Predicate Information (identified by operation id):
16 ---------------------------------------------------
17
18 2 - access("B"."OBJECT_ID"=:B1)
这个例子说明即使oracle强调sql的重用(即使用内存中已经缓存的sql执行计划,避免硬解析),不过它还是很智能的,即使一个sql在不断执行的过程中,仍然能动态调整执行计划,让
sql的性能更加高效。。。。。