当前位置:  开发笔记 > 编程语言 > 正文

为什么oracle存储过程的执行时间会因执行方式而大大增加?

如何解决《为什么oracle存储过程的执行时间会因执行方式而大大增加?》经验,为你挑选了0个好方法。

这是我的问题:我们有一个称为的存储过程,HEAVY_SP并且根据其执行方式,执行时间会大大增加:

(1)通话执行

在Oracle SQL Developer IDE中直接执行

CALL HEAVY_SP(0, 'F', 5, ...)

需要15秒(我们当前的解决方案)

(2)使用播放按钮

使用Oracle SQL Developer打开过程并执行“播放”按钮:

需要15秒

(3) dbms_job:计划模式

需要15秒

(4) dbms_job:即时执行模式

需要超过1个小时

回顾数据处理方式,我们发现每次迭代都很慢。

(5)从SQL_PLUS(Linux)

耗时超过1小时,迭代速度非常慢

(6)从JAVA

耗时超过1小时,迭代速度非常慢

(7)从TOAD

耗时超过1小时,迭代速度非常慢

研究

我们已经吃了很多Google页面,例如:

为什么在存储过程中查询运行比在查询窗口中慢

oracle-pl-sql-procedure-runs比SQL慢

甲骨文在存储过程中插入的速度比手动插入要慢

通过Java相对于直接在数据库上运行,存储过程运行30慢一些

所以我的问题是:

为什么Oracle采取这种方式?

它不应该在所有情况下(相同的参数)都表现得很快吗?

存储过程必须修改吗?

如果查询计划,跟踪文件或统计信息显示不同的行为,则存储过程是否必须固定?

为什么在查询窗口中执行速度很快?

提前致谢。


评论提示

提示1

遵循@BobJarvis关于统计的建议

结果:我们的统计数据是最新的。甚至,我们EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=>'SOME_USER', tabname=>'SOME_TABLE', cascade => TRUE);在所有问题表中重新执行,结果是相同的。


提示#2

遵循@KonstantinSorokin的建议

我怀疑执行计划可能会因会话设置的不同而有所不同。考虑比较v$ses_optimizer_env

结果:我们进行了比较,结果(1)(4)的v $ ses_optimizer_env相同。


提示3

使用此查询:

select s.sid,s.serial#,s.username, s.machine,replace(q.SQL_FULLTEXT,chr(0)) sql_text, s.program, s.logon_time, s.status, s.OSUSER
from v$session s, v$sql q
where 
s.status='ACTIVE'
and s.username is not null 
and s.sql_hash_value = q.hash_value
order by s.LOGON_TIME, s.username;

我注意到机器,程序和其他更改取决于测试:

快速模式(查询窗口)

machine             | program           | ouser
--------------------|------------------ | -------
my laptop username  | SQL DEVELOPER     | User

滞后模式(后台执行)

machine             | program           | ouser
--------------------|------------------ | -------
ip-10-6-7-1         | oracle@ip-10-6-7-1| rdsdb

提示#4

遵循@KonstantinSorokin与痕迹相关的建议。

结果:临时DBA进行了调查,他告诉我们某些sql_id具有不同的执行计划。他的建议是:使用提示。

这可能是解决方案,但是,为什么某些SQL ID具有不同的执行计划?


[解决了]

感谢@ IsaacMejia,NLS_COMP = LINGUISTIC是缓慢执行的原因。因此,java不是问题的原因。Oracle错误配置是导致我们出现问题的原因。

解决方案必须在实例级别为NLS_COMP = BINARY设置正确的值。

但就我而言,我有几个应用程序可以很好地处理此值。因此,为了避免应用程序中的排序和比较问题,我无法覆盖实例NLS设置。

临时解决方案在存储过程的开头执行:

execute immediate 'alter session set NLS_COMP=''BINARY''';

并在完成时返回到先前的值:

execute immediate 'alter session set NLS_COMP=''LINGUISTIC''';

现在,存储过程可以像在查询窗口中直接执行一样快速运行(ORACLE SQL DEVELOPER)

推荐阅读
依然-狠幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有