有没有什么好的方法来客观衡量Oracle 10g中查询的性能?有几个特定的查询,我已经tuning几天。我已经得到了一个似乎运行得更快的版本(至少基于我的初始测试),但是EXPLAIN的成本大致相同。Oracle的EXPLAIN PLAN准确性如何?
- 说明费用缺失的可能性有多大?
- 在说明成本与查询实际表现不成比例的情况下,是否存在特定情况?
- 我在这个查询中使用了first_rows提示。这是否有影响?
有没有什么好的方法来客观衡量Oracle 10g中查询的性能?有几个特定的查询,我已经tuning几天。我已经得到了一个似乎运行得更快的版本(至少基于我的初始测试),但是EXPLAIN的成本大致相同。Oracle的EXPLAIN PLAN准确性如何?
EXPLAIN成本有多少可能缺少某些东西?
非常不可能。实际上,这将是一个级别1
错误:)
实际上,如果您的统计信息从运行EXPLAIN
的时间显着变化,实际查询计划将有所不同。但是,如同查询被编译一样,这个计划将保持不变。
注EXPLAIN PLAN
可以告诉你的东西都是可能发生,但可能永远不会在实际查询发生。
一样,如果你在一个分层查询运行EXPLAIN PLAN
:与指标上都id
和parent
SELECT *
FROM table
START WITH
id = :startid
CONNECT BY
parent = PRIOR id
,你会看到一个额外FULL TABLE SCAN
其中大部分可能不会发生在现实生活。
使用STORED OUTLINE
的存储和重用计划无论如何。
是否存在EXPLAIN成本与查询实际性能不成比例的不同情况?
是的,它经常发生在复杂的查询上。
CBO
(基于成本的优化器)使用计算的统计信息来评估查询时间并选择最优方案。
如果您的查询中有很多JOIN
的子查询和这些类型的东西,它的算法无法准确预测哪个计划会更快,特别是当您达到内存限制时。
这里是你问的具体情况:HASH JOIN
,例如,将需要几个越过probe table
如果哈希表将不适合pga_aggregate_table
,但作为Oracle 10g
,我不记得这个曾经被考虑由CBO
帐户。
这就是为什么我暗示每查询我预计超过2
秒在最坏的情况下运行。
我用了FIRST_ROWS提示此查询。这是否有影响?
这暗示会使优化器使用具有较低响应时间计划:将尽快返回第一行,尽管总体查询时需要更大。
实际上,它几乎总是意味着使用NESTED LOOP
而不是HASH JOIN
's。
NESTED LOOP
在大型数据集上的整体性能较差,但它们返回的第一行更快(因为不需要构建哈希表)。
至于查询从original question,看到我的回答here。
AFAIK,EXPLAIN正在使用一些数据库统计来计算成本,所以它可以明显不同于实际的性能。
根据我的经验EXPLAIN已经准确和有益的。如果不是,它可能不是它的有用工具。你最后一次分析表格的时间是什么时候?我曾经见过解释计划几乎是之前和之后的分析相同,但分析所取得了巨大的性能提升。
问:有没有什么好的方法来客观衡量在Oracle 10g中查询的性能?
http://asktom.oracle.com/tkyte/article1/autotrace.html
(本文移动)
http://tkyte.blogspot.com/2007/04/when-explanation-doesn-sound-quite.html
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:5671636641855
和启用Oracle跟踪在其他环境中并不难。
问:有一个特定的查询,我已经调整了几天。我已经得到了一个似乎运行得更快的版本(至少基于我的初始测试),但是EXPLAIN的成本大致相同。
问:> 1。 EXPLAIN成本有多少可能缺少某些东西?
问:> 2。 EXPLAIN成本与查询的实际性能有何不同?
问:> 3。我在这个查询中使用了first_rows提示。这是否有影响?
/*+ FIRST_ROWS */
)可能会影响优化程序选择哪个计划。“成本” 的解释计划返回的是相对的。这是一个表现的指标,但不是一个准确的衡量标准。您无法将成本编号转换为多个磁盘操作或一定数量的CPU秒数或等待事件数量。
通常情况下,我们发现EXPLAIN PLAN成本显示为1的语句将“非常快”地运行,并且具有EXPLAIN PLAN成本约为5或6位数字的语句将花费更多时间跑步。但不总是。
优化器正在做的是比较许多可能的执行计划(全表扫描,使用索引,嵌套循环连接等)。优化器正在为每个计划分配一个数字,然后选择最低的计划数。
我曾见过EXPLAIN PLAN显示的优化程序计划确实有不是与语句执行时使用的实际计划匹配的情况。我十年前看到Oracle8,特别是当涉及到的语句绑定变量而不是文字时。
要获取语句执行的实际成本,请为您的语句启用跟踪。 最简单的方法是使用SQLPlus AUTOTRACE。
[http://asktom.oracle.com/tkyte/article1/autotrace.html][4]
外sqlplus的环境中,你可以打开的Oracle跟踪:
alter session set timed_statistics = true; alter session set tracefile_identifier = here_is_my_session; alter session set events '10046 trace name context forever, level 12' --alter session set events '10053 trace name context forever, level 1' select /*-- your_statement_here --*/ ... alter session set events '10046 trace name context off' --alter session set events '10053 trace name context off'
这使得跟踪文件到服务器上的目录USER_DUMP_DEST。生成的跟踪文件将具有语句计划和所有等待事件。 (包含在文件名中的指定跟踪文件标识符,并使其更容易找到在UDUMP目录中的文件)
select value from v$parameter where name like 'user_dump_dest'
如果您没有访问跟踪文件,你将需要得到从dba的帮助,让你访问。 (dba可以创建一个简单的shell脚本,开发人员可以针对.trc文件运行tkprof,并更改跟踪文件和tkprof输出的权限,也可以使用较新的trcanlzr。都是。
+1,xlnt,有见地的答案,照常。那么,你是否睡在枕头下的Oracle RDBMS源代码或什么东西? ;-) – DCookie 2009-05-06 14:49:41