避开绑定变量的弱点的一个经典解决方案——《Oracle高效设计》学习笔记

假如我们在应用程序中对数据库进行查询时,经常会对某个字段使用Like语句,而数据库是对这个字段添加了索引的,如果查询的sql中like

 

的内容是以%开头的,那么索引很可能会被忽略,但当like的内容不是以%开头的,索引会被利用。假设这个查询会被经常使用,我们希望对

 

于这些查询使用绑定变量,这样可以减少硬解析的次数,但使用绑定变量的代价是,在查询时我们很可能使用错误的查询计划。

 

对于这个问题《Oracle高效设计》中给出了一个很经典的解决方案,使得我们在使用绑定变量同时,也能够使用正确的查询计划。

 

先做一个实验:

create table t
as
select a.* from all_objects a;
create index t_idx on t(object_name);

analyze table t compute statistics
for table for all indexes for all indexed columns;

variable x varchar2(50)
alter session set sql_trace=true;
set termout off
exec :x := '%';
select * from t x_was_percent where object_name like :x;
exec :x := 'Y%';
select * from t x_was_NOT_PCT where object_name like :x;

 

使用tkprof工具,查看跟踪结果:

 

BEGIN :x := '%'; END;

select *
from
 t x_was_percent where object_name like :x

 

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 5 

 

Rows     Row Source Operation
-------  ---------------------------------------------------
  49654  TABLE ACCESS FULL T (cr=3950 pr=0 pw=0 time=198752 us)

 

BEGIN :x := 'Y%'; END;
select *
from
 t x_was_NOT_PCT where object_name like :x

 

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 5 

Rows     Row Source Operation
-------  ---------------------------------------------------
      1  TABLE ACCESS BY INDEX ROWID T (cr=4 pr=0 pw=0 time=69 us)
      1   INDEX RANGE SCAN T_IDX (cr=3 pr=0 pw=0 time=31 us)(object id 52917)

 

从测试结果可以看出,两个查询都使用了正确的查询计划。由于Oracle会在第一次执行绑定变量的sql时,

 

使用绑定变量窥视技术(根据绑定变量实际值确定查询计划),又因为,我们对于两个查询做了点改动(注意黑体,

 

第一条sql的t被命名为x_was_percent ,第二条sql的t被命名为x_was_NOT_PCT ),

 

使得Oracle把这两个相同的查询做为不同查询来看待,每个查询都解析了一遍,这就使得两个查询都使用了正确的

 

查询计划,只要保证程序,在后续的类似查询凡是以%号开头的,都使用第一条sql,如果不以%开头的都使用第二

 

条sql,就可以保证虽然使用了绑定变量,但每次查询都使用了正确的查询计划。

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值