执行计划的动态切换

之前我一直以为同样一个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的性能更加高效。。。。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值