这里两天都在对一条sql进行调优。该sql并不复杂,类似于
select ... from some_view
union all
select ... from some_table where datetime >= d1 and datetime< d2 and ....
底层使用ibatis2.1.6 + oracle 10g。
接到任务就像通常那样查看CBO生成的执行计划;一看就知道问题的所在--"Full table scan"(面对那样的多分区大表,这个选择实在太差),稍微修改一下查询条件选择了一个有global index的时间字段来替代;再在sql developer上试运行了一下,结果很满意--从原来的12s下降到了0.5s左右。ok,提交代码。本想着这就完事儿了,接下来出现了戏剧性的一幕:
引用一下我在twitter上的原话
“@JoardSpike
这该死的Oracle CBO,无论你使用sqlplus, Toad还是sql developer在targe DB上调试出多么完美的执行计划,一旦上了应用,一样让你蛋疼。”
出现了这样的话,想必就知道为啥了?无论怎么样通过app访问测试数据库,该sql和以前一样慢。God!新的执行计划还是全表扫描,但是在其他client里却能正确执行。
一招不行来第二招,这种不一致的情况以前也有过,ok,把视图拿下换上原表,然后加上index hint。结果还是不行,这次虽然走索引了,但是用的却不是我“提示”的索引。通常招数不行了,来更狠的。
重新收集表的统计信息。不行... :(
重建索引。还是不行... wo kao
备份数据,truncate源表,重建表,为了节省时间,随便还再次重建索引。依然不行....晕
清空shared_pool,强制让CBO为该sql生成新的执行计划。仍然不行...
劫持DBA,一同调试,也没有找到原因。
时间就这么过去了!!!
当我对CBO一筹莫展之际,逐步把怀疑的目光移向了应用程序。首先,在ibatis里使用的map作为parameterClass,而且使用的绑定变量,难道会是这个原因?问题会出现在这种基本处理上?首先将变量中的时间改成格式化为字符串,并在sql中在显示进行类型转换“datetime >= to_date(d1, 'yyyy-MM-dd hh24:mi:ss')”。执行计划回归正常。这个过程总只花了很少的时间。
从上述情况来看,很有可能ibatis在处理Date时未能正确经行转换,导致oracle对datetime字段进行了隐式类型转换,最终CBO未能使用该列的全局索引。
当然,也有可能是oracle driver有问题?也许... ...
下班了咯!现在暂时就不深究了!
不过各位同学有没有类似经验?ibatis2里会出现这种基础问题?还请告之 嘿嘿 :)
------------顽强的分隔符------------
其实这个绑定变量的潜在问题,Tom在《Oracle高效设》就提到过,需要同学们多注意,我这次就是忘记了这点,浪费了不少时间。但最主要的原因,也是我本次写blog要记录的问题--思维定势。就像以前总结的那样,CBO大部分情况下都是正确的,不要老是怀疑CBO有问题,先找找自己的问题,最后再来怀疑那些成熟的(开源)产品。
------------顽强的分隔符------------
在啰嗦两句。对那些才接触oracle的同学,看看这两类写法在oracle上会有多大的性能差异:
select * from (
select * from table_gmail
union all
select * from table_gdoc
) t where name = 'google' order by ...
和
select * from (
select * from table_gmail where name = 'google'
union all
select * from table_gdoc where name = 'google'
) order by ...
------------顽强的分隔符------------
(updated at 2010-1-18)
今天花了些时间继续研究这个问题,导致该问题的原因的确是“导致oracle对datetime字段进行了隐式类型转换,最终CBO未能使用该列的全局索引”,不过问题不是出在ibatis上而是oracle driver。
我会再写一blog记录具体原因。
分享到:
相关推荐
oracle sql调优培训大纲
NULL 博文链接:https://zhengfc323.iteye.com/blog/1455767
Oracle Sql性能调优,内部培训文档
Oracle SQL调优.pptx
sql调优 oracle sql调优技术文档
实战Oracle SQL调优 hint特性
oracle sql级别调优及书写原则,重点是使用索引及索引覆盖
ORACLE 19C SQL调优指南 中文版,很牛逼的文档,Oracle DBA必备
大传授Oracle SQL调优精要,重要的是思想!
oracle SQL 调优.emmx
Oracle 性能调优需要通过八个步骤来实现,包括设立合理的 Oracle 性能优化目标、测量并记录当前性能、确定当前 Oracle 性能瓶颈、把等待事件记入跟踪文件、确定当前的 OS 瓶颈、优化所需的成分、跟踪并实施更改控制...
Oracle 19C SQL调优优化指南,全面提升SQL优化能力,DBA必备,开发必备
oracle, sql 全面得介绍如何调优sql,写出高效的sql语句
OracleSQL调优[参照].pdf
介绍oracle的执行计划概念,和如何对sql进行优化
oracle sql调优,相信你一定能受益匪浅
从原理到实践详细讲解了sql调优的细节,值得评鉴
ORACLE执行计划和SQL调优.pptx
ORACLE_SQL调优老方块出品,深入讲解了ORACLE原理及常见SQL调优技巧