执行计划成本估算

时间:2012-08-01 06:46:40

标签: sql performance oracle

有一个问题,我必须根据某些条件更新一个包含数百万条记录的表。我已经编写了一个长shell脚本和SQL语句来执行它。为了检查性能,我打算使用解释计划,从http://docs.oracle.com/cd/B10500_01/server.920/a96533/ex_plan.htm#19259

学习它

这里写道:“执行计划因以下原因而有所不同:” 不同的成本 - > 数据量和统计数据 绑定变量类型 初始化参数 - 全局或会话级别设置

在这里,我不明白初始化参数 - 全局设置或会话级别如何影响执行计划。 任何人都能解释一下吗? 除了解释计划或autotrace之外,还有其他方法可以检查SQL语句的性能。

3 个答案:

答案 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
  • 注意级别8用于跟踪WAITS。你可以做4级(绑定变量)和12级(绑定和等待),但我总是发现问题只是8级.12级也可能需要更长的时间来执行和完整大小的环境。

现在运行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开始,可能会获得几秒但是在整体方案无助于缩短整体运行时间。

如果可以的话,尽量减少更新语句的数量,就好像你有一个大表一样,如果你可以在表的一次传递中做更新(并且有支持更新的索引)而不是做了很多小小的更新。

如果您需要更多帮助,也许您可​​以发布脚本的相关部分,运行所需的总时间以及解释计划。