2

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

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

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

4

3 回答 3

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');
于 2012-08-01T08:28:16.537 回答
1

就我个人而言,我只信任行源操作,因为这给出了执行时的确切计划。确实存在一些影响计划构建方式的参数。大多数参数将在实例级别设置,但可以在会话级别覆盖。这意味着每个会话都可以有自己的一组有效参数。

您遇到的问题是您需要知道要运行脚本的会话的确切设置。有几种方法可以更改会话级别设置。可以在登录触发器、存储过程或脚本中更改设置。

如果您的脚本不受登录触发器的影响并且不调用任何发出alter session语句的代码,那么您将使用您的实例具有的设置。

于 2012-08-01T07:49:53.740 回答
1

全局或会话参数 Oracle 设置有一组初始化参数。如果未指定任何内容来覆盖它们,则默认情况下将使用它们。它们可以通过使用 ALTER SESSION(仅影响单个用户)或 ALTER SYSTEM(影响所有用户,直到 Oracle 重新启动)命令在会话或系统级别更改内容或通过在代码中使用优化器提示来覆盖。这些可能会对您看到的计划产生影响。

关于解释计划,不同的 Oracle 数据库可能具有不同的初始化参数或设置了一些会话/系统参数,这可能意味着 SAME 代码的行为不同(与另一个 Oracle 数据库相比,在一个 Oracle 数据库上获得不同的执行计划)。

此外,由于执行计划受所选数据的影响,因此在 TEST 中运行良好的查询或包可能永远不会在数据量大得多的 PRODUCTION 中完成。当代码没有使用准确的数据量进行测试时,这是一个常见的问题(或者至少使用从生产数据库导入的表统计信息,如果测试不能保存完整的生产数据量)。

跟踪 到目前为止的建议告诉您如何跟踪单个语句,假设您知道哪个语句有问题,但您提到您有一个包含多个 SQL 语句的 shell 脚本。

如果您使用的此处文档只需一次调用 SQL 并包含多个类似这样的 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 开始无助于减少整体运行时间。

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

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

于 2012-08-01T12:52:47.190 回答