在 Oracle 10g 中有什么好的方法可以客观地衡量查询的性能吗?几天来我一直在调整一个特定的查询。我得到了一个似乎运行得更快的版本(至少基于我的初始测试),但 EXPLAIN 成本大致相同。
- EXPLAIN 成本遗漏某些东西的可能性有多大?
- 是否存在 EXPLAIN 成本与查询的实际性能不成比例的特殊情况?
- 我在这个查询中使用了 first_rows 提示。这有影响吗?
在 Oracle 10g 中有什么好的方法可以客观地衡量查询的性能吗?几天来我一直在调整一个特定的查询。我得到了一个似乎运行得更快的版本(至少基于我的初始测试),但 EXPLAIN 成本大致相同。
EXPLAIN 成本遗漏某些东西的可能性有多大?
非常不可能。实际上,这将是一个级别1
错误:)
实际上,如果您的统计数据在运行时发生了显着变化EXPLAIN
,那么实际的查询计划会有所不同。但是一旦查询完成,计划将保持不变。
注意EXPLAIN PLAN
可能会向您显示在实际查询中可能发生但可能永远不会发生的事情。
就像,如果您EXPLAIN PLAN
在分层查询上运行:
SELECT *
FROM table
START WITH
id = :startid
CONNECT BY
parent = PRIOR id
id
在和上都有索引parent
,你会看到一个额外的东西FULL TABLE SCAN
,这在现实生活中很可能不会发生。
STORED OUTLINE
无论如何都使用's 来存储和重用计划。
是否存在 EXPLAIN 成本与查询的实际性能不成比例的特殊情况?
是的,它经常发生在复杂的查询中。
CBO
(基于成本的优化器)使用计算的统计信息来评估查询时间并选择最佳计划。
如果你的查询中有很多JOIN
's、子查询和这些类型的东西,它的算法无法准确预测哪个计划会更快,尤其是当你达到内存限制时。
这是您询问的特定情况:HASH JOIN
例如,probe table
如果哈希表不适合,则需要多次传递pga_aggregate_table
,但截至Oracle 10g
,我不记得曾经考虑过这一点CBO
。
这就是为什么我暗示我希望在最坏的情况下运行超过几秒钟的每个查询。2
我在这个查询中使用了 first_rows 提示。这有影响吗?
此提示将使优化器使用响应时间较短的计划:尽管总体查询时间较长,但它将尽快返回第一行。
实际上,它几乎总是意味着使用NESTED LOOP
's 而不是HASH JOIN
's。
NESTED LOOP
的在大型数据集上的整体性能较差,但它们返回第一行的速度更快(因为不需要构建哈希表)。
问:在 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 */
)都可能影响优化器选择的计划。EXPLAIN PLAN 返回的“成本”是相对的。这是一个性能指标,但不是一个准确的衡量标准。您无法将成本数字转换为磁盘操作数或 CPU 秒数或等待事件数。
通常,我们发现一条 EXPLAIN PLAN 成本显示为 1 的语句将“非常快”地运行,而一条 EXPLAIN PLAN 成本为五或六位数的语句将需要更多时间来运行。但不总是。
优化器所做的是比较许多可能的执行计划(全表扫描、使用索引、嵌套循环连接等)。优化器为每个计划分配一个编号,然后选择编号最小的计划。
我见过 EXPLAIN PLAN 显示的优化器计划与执行语句时使用的实际计划不匹配的情况。十年前,我在 Oracle8 中看到了这一点,特别是当语句涉及绑定变量而不是文字时。
要获取语句执行的实际成本,请为您的语句启用跟踪。最简单的方法是使用 SQLPlus AUTOTRACE。
[http://asktom.oracle.com/tkyte/article1/autotrace.html][4]
在 SQLPlus 环境之外,您可以打开 Oracle 跟踪:
更改会话设置 timed_statistics = true; 更改会话集 tracefile_identifier = here_is_my_session; 更改会话集事件'10046 永远跟踪名称上下文,级别 12' --alter session set events '10053 永远跟踪名称上下文,级别 1' 选择 /*-- your_statement_here --*/ ... 更改会话集事件“10046 跟踪名称上下文关闭” --alter session set events '10053 跟踪名称上下文关闭'
这会将跟踪文件放入服务器上的 user_dump_dest 目录中。生成的跟踪文件将包含语句计划和所有等待事件。(分配的跟踪文件标识符包含在文件名中,便于在 udump 目录中找到您的文件)
从 v$parameter 中选择值,其中名称如 'user_dump_dest'
如果您无权访问跟踪文件,则需要从 dba 获得帮助才能访问。(dba 可以创建一个简单的 shell 脚本,开发人员可以针对 .trc 文件运行该脚本以运行 tkprof,并更改跟踪文件和 tkprof 输出的权限。您还可以使用较新的 trcanlzr。Oracle metalink 上有关于两个都。
AFAIK,EXPLAIN 正在使用一些数据库统计信息来计算成本,因此它肯定会与实际性能有所不同。
根据我的经验,EXPLAIN 是准确且有益的。如果不是,它可能不是有用的工具。你最后一次分析表格是什么时候?我已经看到解释计划在分析之前和之后几乎相同的地方,但是分析带来了巨大的性能提升。