http://www.itpub.net/428148.html
我最近遇到一个sql的优化问题,由于受到许多限制,想了许久终于找到解决方法:
sql语句如下:
SELECT COUNT (*) FROM kc24
WHERE aae040 >= :b1
AND aae040 AND akb020 LIKE :b3 AND akc021 LIKE :b4 AND aka130 LIKE :b5
AND aab001 LIKE :b6 AND SUBSTR (aae072, 1, 1) != '_'
AND akc501 = :b7
KC24表上在akb020加上其他两个字段(包括aae072)作为主键索引,aae040为日期型
变量,并建立了索引。由于akb020这个字段非常特殊,其所有的值都是一样的。表大小
120M,记录数为703XXX,主键索引PK_KC24为29M(压缩了字段1),i_kc24_aae040索引
为14M.我重新分析了表,我发现执行计划还是使用PK_KC24索引,这样实际上还不如选择
全表扫描。
我又分析了表,加入直方图的统计,执行计划依旧。最终我发现optimizer_index_cost_adj,
optimizer_index_caching设置影响了执行计划。不过很奇怪的是如果没有这一行
AND SUBSTR (aae072, 1, 1) != '_',执行计划就会使用aae040的索引。
optimezer*的参数我不能再修改,因为这个参数已经经过测试,已经设置在最佳模式。
使用的数据库是oracle8i的标准版,程序是第3方开发的,又不能修改代码,标准版又不支
持大纲(我个人并不喜欢使用这种方式),到这里优化陷入困境。。。。
后来我想如果能够修改统计信息,人为的加大PK_KC24索引的统计大小,就可以改变执行计划,
仔细看看书,dbms_stats可以修改统计信息,不过修改统计信息,一定要检查相关kc24的sql语句,
否则可能影响别的sql语句执行计划。
EXECUTE SYS.DBMS_STATS.set_index_stats (OWNNAME=>'TEST', INDNAME=>'PK_KC24', numlblks=> 8000);
在检查执行计划,发现能使用aae040索引,并且在检查相关的kc24的sql语句,没有问题,整个优化完成。