因为第一次遇到这个问题,所以以下方法,都来源于网上。
版本:oracle11g
遇到这个问题,可以查看oracle日志,分析问题的原因。
oracle数据库的最常用问题定位日志是alert日志,oracle数据库的日志文件alert_$ORACLE_SID.log记录了重作日志的转换,数据库启动和关闭,数据库结构的改变,回退段的修改,死锁,内部错误等信息。
路径是:ORACLE_BASE/admin/ORACLE_SID/bdump/alert_ORACLE_SID.log
新的Oracle数据库的日志文件在ORACLE_BASE/diag/rdbms下面,如:D:\app\Administrator\diag\rdbms\orcl\orcl\trace
也可以通过sql语句查找位置:
Alert log XML文件位置:select value from v$diag_info where name ='Diag Alert';
Alert log文本文件位置:select value from v$diag_info where name ='Diag Trace';
解决方法1:
alter system set "_optimizer_connect_by_cost_based" = false scope=both ;
参考
_optimizer_connect_by_cost_based 为使用基于成本的转换进行连接,默认为true
scope 就是这个参数修改的SQL的影响的范围,总共有三个值:both、memory,spfile。
1.scope=memory修改后当前就起作用,重启数据库不起作用
2.scope=spfile修改后当前不起作用,下次重启数据库才起作用
3.scope=both修改后当前起作用,下次重启数据库也起作用
更多未归档隐藏参数,参考
解决方法2:
alter system set "_optim_peek_user_binds"=false;
_optim_peek_user_binds 为能够窥视用户绑定,默认为true
开启bind主要是为了提高性能,因为这样做可以尽量避免不必要的硬分析(Hard Parse),节约了时间,同时节约了大量的CPU资源。
当一个Client提交一条Sql给Oracle后,Oracle 首先会对其进行解析(Parse),然后将解析结果提交给优化器(Optimiser)来进行优化而取得Oracle认为的最优的Query Plan,
然后再按照这个最优的Plan来执行这个Sql语句(当然在这之中如果只需要软解析的话会少部分步骤)。
当Oracle接到Client提交的Sql后会首先在共享池(Shared Pool)里面去查找是否有之前 已经解析好的与刚接到的这一个Sql完全相同的Sql
(注意这里说的是完全相同,既要求语句上的字符级别的完全相同,又要求涉及的对象也必须完全相同)。
当发现有相同的以后解析器就不再对新的Sql在此解析而直接用之前解析好的结果了。这里就节约了解析时间以及解析时候消耗的CPU资源。尤其是在OLTP中运行着的大量的短小Sql,效果就会比较明显了。
因为一条两条Sql的时间可能不会有多少感觉,但是当量大了以后就会有比较明显的感觉了。
但是,使用绑定变量的一个缺点是,给出的执行计划并不一定就是SQL在真正应用程序里所使用的执行计划。这时我们就可以通过event 10053 事件来查看。
解决方法3:
如果临时表空间不能自动扩展的话,可以给用户新建临时表空间。
1、新建一个临时表空间
2、将当前用户的临时表空间切换到新建的临时表空间上