最近遇到一个很诡异的现象: 在存储过程中写入一张表的数据,语句很简单,就是insert …… select …… where…… 在where 条件中一旦使用了过程的传入参数,执行就非常慢(无法忍受的慢) 如果将insert 语句拼成字符串,动态执行,则没有上述问题,
 
 如果将过程中的sql语句提出,where条件中引用参数的地方给定一个具体的值,也没有上述问题。
 

解决方案 »

  1.   

    这就是SQL解析中的软硬解析问题
    where 条件中一旦使用了过程的传入参数 这样每次Oracle都会去解析这个SQL,属于硬解析
    而采用动态SQL拼接或者where条件固定,就只需解析一次
    因此你说的慢,主要在于解析时间耗费较多  
      

  2.   

    不会吧.
    plsql一般会自动使用绑定变量的.倒是你用动态sql而且不用using传入变量的时候可能会导致硬解析.
      

  3.   

    是否你传入的变量类型不对,导致了ORACLE内部进行转换造成的?
    例如字符串和数字的区别
      

  4.   

    应该是绑定变量窥探导致的在存储过程中的select语句使用了错误的执行计划.比如由于绑定变量窥探导致优化器认为where条件中的值会产生大部分表行扫描,使用索引成本将高于全表扫描方式,于是它摒弃了使用索引的方式.
    解决的办法就是用优化提示指定使用索引,或者为索引列收集直方图统计信息指导优化器采用更合理的访问路径
      

  5.   

    楼主的SQL语句中没有循环,只执行一次,我认为不太可能是因为绑定变量的窥测导致执行计划错误,
    我觉得是不是ORACLE内部进行了转换是绑定变量失效造成的。发下执行计划
      

  6.   

    这么说的话 的看你是否传人的值跟where 后面的比对的时候 发生了类型的隐性转换
      

  7.   

    哦,问题已经解决了很久了,忘了结贴了。
    问题其实是这样造成的:
    由于from使用的是个按月叠加的事实表。
    每月数据增量几乎一致在400W行左右,
    程序中,数据加载成功后,就开始上述的insert.条件中也使用了期别。由于数据量在表中数据期数少的时候,变化的百分比比较大,所以之前执行的执行计划就不适用与
    数据变化之后的查询。
    解决的办法是:每次数据叠加成功后,重新更新表状态,收集表、索引信息。
    让优化器重新解析sql.不使用原来的执行计划就行了。谢谢大家。