有一个问题,我必须根据某些条件更新一个包含数百万条记录的表。我已经编写了一个长shell脚本和SQL语句来执行它。为了检查性能,我打算使用解释计划,从http://docs.oracle.com/cd/B10500_01/server.920/a96533/ex_plan.htm#19259
学习它这里写道:“执行计划因以下原因而有所不同:” 不同的成本 - > 数据量和统计数据 绑定变量类型 初始化参数 - 全局或会话级别设置
在这里,我不明白初始化参数 - 全局设置或会话级别如何影响执行计划。 任何人都能解释一下吗? 除了解释计划或autotrace之外,还有其他方法可以检查SQL语句的性能。
答案 0 :(得分:3)
有几个(初始化)参数可以影响您的语句的执行计划。立即想到的是OPTIMIZER_MODE
其他不太明显的会话是NLS设置之类的东西,可能会影响索引的可用性。
获取实际执行计划的另一种方法(除了跟踪会话和使用tkprof)是使用/*+ gather_plan_statistics */
提示和'dbms_xplan.display_cursor()'。
这是通过首先使用上面的提示实际运行语句来完成的(所以这需要比“正常”解释更长的时间):
select /*+ gather_plan_statistics */ *
from some_table
join ...
where ...
然后在该语句完成后,您可以使用dbms_xplan检索使用的计划:
SELECT *
FROM table(dbms_xplan.display_cursor(format => 'ALLSTATS LAST');
答案 1 :(得分:1)
我个人只信任rowsource操作,因为这会给出执行时的确切计划。确实存在一些影响计划构建方式的参数。大多数参数将在实例级别设置,但可以在会话级别上覆盖。这意味着每个会话都可以拥有自己的一组有效参数。
问题在于您需要知道将运行脚本的会话的确切设置。有几种方法可以更改会话级别设置。可以在登录触发器,存储过程或脚本中更改设置。
如果您的脚本不受登录触发器的影响,并且不会调用任何发出alter session
语句的代码,那么您将使用您的实例所具有的设置。
答案 2 :(得分:1)
GLOBAL OR SESSION参数 Oracle使用一组初始化参数进行设置。如果没有指定任何内容来覆盖它们,则默认使用这些。可以使用ALTER SESSION(仅影响单个用户)或ALTER SYSTEM(在重新启动Oracle之前影响所有用户)命令来覆盖它们,以在会话或系统级别更改内容或在代码中使用优化器提示。这些可能会对您看到的计划产生影响。
关于解释计划,不同的Oracle数据库可能具有不同的初始化参数或设置了一些会话/系统参数,这可能意味着SAME代码的行为不同(通过在一个Oracle数据库上获取与另一个Oracle数据库相比的不同执行计划)。
此外,由于执行计划受所选数据的影响,因此在TEST中运行正常的查询或程序包可能永远不会在PRODUCTION中完成,其中数据量要大得多。当代码未使用准确的数据量进行测试时(或者至少使用从生产数据库导入的表统计信息,如果测试无法保存完整的生产量,如数据),这是一个常见问题。
<强>示踪强> 到目前为止的建议告诉您如何跟踪单个语句,假设您知道哪个语句有问题但是您提到您有一个包含多个SQL语句的shell脚本。
如果您使用的是一个只调用SQL的here文档,并包含几个这样的SQL语句......
#!/bin/ksh
sqlplus -S user/pass <<EOF
set heading off
BEGIN
-- DO YOUR FIRST SQL HERE
-- DO YOUR SECOND SQL HERE
END;
/
EOF
...您可以像这样创建一个oracle跟踪文件
#!/bin/ksh
sqlplus -S user/pass <<EOF
set heading off
BEGIN
ALTER SESSION SET EVENTS '10046 trace name context forever, level 8'
-- DO YOUR FIRST SQL HERE
-- DO YOUR SECOND SQL HERE
END;
/
EOF
现在运行shell脚本执行单个执行,然后使用
检查在SQL PLUS中创建跟踪文件的位置 SQL> show parameter user_dump_dest
/app/oracle/admin/rms/udump
转到该目录,如果没有启用其他跟踪,则会有一个.trc文件,其中包含脚本中整个SQL运行的跟踪。
您需要使用unix tkprof命令将此转换为可读格式,如此
unix> tkprof your.trc ~/your.prf sys=no sort=fchela,exeela
现在更改到您的主目录,将会有一个.prf文件,其中列出的SQL语句按照执行时间最多或获取时间与解释计划一起执行的顺序列出。这组tkprof参数使您可以专注于修复时间最长的语句,从而获得最大的调整回报。
请注意,如果您的shell脚本运行多个sqlplus命令,则每个命令都会创建一个单独的会话,因此为每个命令添加一个ALTER SESSION语句将创建单独的跟踪文件。
另外,不要忘记它很容易迷失在细节中,有时调整是关于查看整体情况并以另一种方式做同样的事情,而不是从单个SQL开始,可能会获得几秒但是在整体方案无助于缩短整体运行时间。
如果可以的话,尽量减少更新语句的数量,就好像你有一个大表一样,如果你可以在表的一次传递中做更新(并且有支持更新的索引)而不是做了很多小小的更新。
如果您需要更多帮助,也许您可以发布脚本的相关部分,运行所需的总时间以及解释计划。