首页 > 新闻系统 > 编程天地 > 文章正文

oracle使用绑定变量性能反而更差?

2008-04-14 16:38:08 来源:中国自学编程网 作者:佚名 点击:
当我在做培训时,在解释绑定变量的好处时,大家都比较容易理解。但是,对于并不是任何时候绑定变量都是最优的。这一点很多人不是和理解。

     当我在做培训时,在解释绑定变量的好处时,大家都比较容易理解。但是,对于并不是任何时候绑定变量都是最优的。这一点很多人不是和理解。下面就讨论一下在什么时候会出现绑定变量会使性能变差。

  扫描成本和optimizer_index_cost_adj

  我们知道,在cbo模式下,oracle会计算各个访问路径的代价,采用最小代价的访问路径作为语句的执行计划。而对于索引的访问代价的计算,需要根据一个系统参数optimizer_index_cost_adj来转换为与全表扫描代价等价的一个值。这是什么意思呢?我们先稍微解释一下这个参数:optimizer_index_cost_adj。它的值是一个百分比,默认是100,取值范围是1~10000。当估算索引扫描代价时,会将索引的原始代价值乘以这个百分比,将换算后的值作为与全表扫描代价比较的值。也就是说,当这个值为100时,计算出的索引扫描代价就是它的原始代价:

cost_com = cost_org * optimizer_index_cost_adj/100

  看以下例子:

sql> create table t_peeking (a number, b char(1), c char(2000));

table created.

sql>
sql> create index t_peeking_idx1 on t_peeking(b);

index created.


sql> begin
2 for i in 1..1000 loop
3 insert into t_peeking values (i, 'a', i);
4 end loop;
5
6 insert into t_peeking values (1001, 'b', 1001);
7 insert into t_peeking values (1002, 'b', 1002);
8 insert into t_peeking values (1003, 'c', 1003);
9
10 commit;
11 end;
12 /

pl/sql procedure successfully completed.

  注意,我们给索引字段b插入的值中只有3个distinct值,记录数是1003,它的集的势很高(1003/3)=334。

sql>
sql> analyze table t_peeking compute
statistics for table for all indexes for all indexed columns;

table analyzed.

sql>

  我们看下索引扫描的代价是多少:

sql> show parameter optimizer_index_cost_adj

name type value
------------------------------------ ----------- ------
optimizer_index_cost_adj integer 100

sql> delete from plan_table;

0 rows deleted.

sql>

sql> explain plan for select
/*+index(a t_peeking_idx1)*/ * from t_peeking a where b = :v;

explained.

sql> select lpad(' ', 2*(level-1))||operation||' '||options||' '||
2 object_name||' '||decode(id, 0, 'cost='||position) "query
3 plan_table"
4 from plan_table
5 start with id = 0
6 connect by prior id = parent_id
7 ;

query
plan_table
-----------------------------------------------------
select statement cost=113
table access by index rowid t_peeking
index range scan t_peeking_idx1

sql>

  再看全表扫描的代价是多少:

sql> delete from plan_table;

3 rows deleted.

sql>
sql> explain plan for select
/*+full(a)*/ * from t_peeking a where b = :v;

explained.

sql>
sql> select lpad(' ', 2*(level-1))||operation||' '||options||' '||
2 object_name||' '||decode(id, 0, 'cost='||position) "query
3 plan_table"
4 from plan_table
5 start with id = 0
6 connect by prior id = parent_id
7 ;

query
plan_table
----------------------------------------------------
select statement cost=75
table access full t_peeking

sql>

9 7 3 1 2 3 4 4 8 :

精彩推荐
焦点大图推荐
本类热门文章

论坛美图

广告联系 | 版权说明 | 意见建议 | 加入收藏 | 军网站群 [ 军软件园 - 军软件商城 - 军软件园论坛 ]

电信与信息服务业务经营许可证:京ICP证050203