基本要素(时间、用户、问题)
用户11g环境下有段SQL语句在程序中执行效率非常差,但是在plsql中执行却很快,通过查看执行计划,发现使用了不同的索引导致,程序中执行的如下:
PLSQL中执行的效果如下:
可以看到差别,使用门诊费用记录_IX_登记时间索引是在plsql中的执行计划,使用门诊费用记录_UQ_NO的是程序中的执行计划,两者SQL是完全相同的,唯一却别就是前者使用了绑定变量,后者是直接带参数值执行。
问题分析
问题很明显,由于绑定变量生成的执行计划与实际有偏差,11g本来有个绑定变量窥探的功能,但是明显在这里没有用,分析极有可能是统计信息出现了问题,需要重新对相关业务表进行统计信息收集,让相应SQL重新生成执行计划。
解决步骤
重新收集下相关业务表的统计信息,这里我们要注意,建议100%的收集,如果采用采样收集,可能无法准确生成直方图,同样会导致执行计划偏差,执行下面的语句:
exec dbms_stats.gather_table_stats(ownname => 'ZLHIS',tabname =>'门诊费用记录',estimate_percent => 100,method_opt =>'for all indexed columns size 254',no_invalidate => false,cascade => true,force => true,degree =>4);这里我们加了no_invalidate => false, 该参数表示收集完统计信息后,重新生成设计该对象的SQL语句的执行计划,执行完成后,再次查看执行计划正确,系统正常运行。
关键知识点
有绑定变量的SQL语句,如果出现执行计划偏差,建议重新收集下相关业务表的统计信息。