2012-08-01 85 views
2

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

这被写“执行计划可以不同由于以下内容:”研究它 不同成本 - > 数据量和统计 绑定变量类型 初始化参数 - 在全局或设置会话级别

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

回答

1

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

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

此外,由于执行计划受所选数据的影响,因此可能在TEST中运行正常的查询或程序包在数据量更大的PRODUCTION中不会完成。如果代码没有使用精确的数据量进行测试(或者如果测试不能像数据一样保持全部生产量时至少使用从生产数据库导入的表统计信息),则这是一个常见问题。

示踪 的建议,到目前为止,告诉你如何跟踪单独声明假设你知道哪个语句有问题,但你提到你有几个SQL语句的shell脚本。

如果您使用的是带有对SQL加上containin这样几个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 

将此转换为可读格式现在切换到你的主目录,并会出现在这些顺序列出了SQL语句的.prf文件采取最多的执行时间或获取时间与解释计划一起执行。 tkprof的这组参数使您能够专注于修复花费时间最长的语句,从而获得最大的调整回报。

请注意,如果您的shell脚本运行多个sqlplus命令,则每个命令都会创建一个单独的会话,因此向每个会话添加ALTER SESSION语句将创建单独的跟踪文件。

此外,不要忘记,它很容易迷失在细节中,有时调整是关于查看整体图片,并以另一种方式做同样的事情,而不是从一个可能获得几秒钟的单一SQL开始,在整体方案中并不有助于减少整体运行时间。

如果可以,尽量减少更新语句的数量,就好像您有一个大表一样,如果您可以在表中执行一次更新(并且支持更新的索引),那么效率会更高比做很多小的更新。

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

1

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

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

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

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');