35

在 oracle 10gr2 上,我有几个要比较性能的 sql 查询。但是在它们第一次运行之后,v$sql 表存储了用于缓存的执行计划,因此对于其中一个查询,我从第一次运行时的 28 秒到运行后的 0.5 秒。

我试过了

ALTER SYSTEM FLUSH BUFFER_CACHE;

运行此之后,查询始终以 5 秒运行,我认为这不准确。

想也许从缓存中删除行项目本身:

delete from v$sql where sql_text like 'select * from....

但我收到一个关于无法从视图中删除的错误。

4

3 回答 3

55

彼得回答了你提出的问题。

alter system flush shared_pool;

那就是您将用来“从缓存中删除准备好的语句”的语句。

(准备好的语句不是从共享池中刷新的唯一对象,该语句的作用不止于此。)

正如我在之前的评论(关于您的问题)中指出的那样,v$sql不是表格。它是一个动态性能视图,是 Oracle 内部内存结构的一种方便的类似表的表示形式。您对动态性能视图只有 SELECT 权限,不能从中删除行。


刷新共享池和缓冲区缓存?

以下内容不直接回答您的问题。相反,它回答了一个根本不同(也许更重要)的问题:

我们通常应该刷新共享池和/或缓冲区缓存来衡量查询的性能吗?

简而言之,答案是否定的。

我认为 Tom Kyte 很好地解决了这个问题:

http://www.oracle.com/technology/oramag/oracle/03-jul/o43asktom.html
http://www.oracle.com/technetwork/issue-archive/o43asktom-094944.html

<摘录>

实际上,重要的是调整工具不要这样做。重要的是运行测试,忽略结果,然后运行两到三遍并平均这些结果。在现实世界中,缓冲区缓存永远不会没有结果。绝不。调整时,您的目标是减少逻辑 I/O (LIO),因为这样物理 I/O (PIO) 将自行处理。

考虑一下:刷新共享池和缓冲区缓存比不刷新它们更加人为。我怀疑,大多数人似乎对此持怀疑态度,因为它违背了传统智慧。我将向您展示如何执行此操作,但不是为了让您可以将其用于测试。相反,我将用它来证明为什么它是徒劳的和完全人为的练习(因此会导致错误的假设)。我刚刚启动了我的电脑,我已经对一个大表运行了这个查询。我“刷新”缓冲区缓存并再次运行它:

</摘录>

我认为汤姆凯特是完全正确的。在解决性能问题方面,我认为“清除 oracle 执行计划缓存”通常不是可靠基准测试的步骤。

让我们解决对性能的担忧。

您告诉我们,您观察到与后续执行(约 5 秒)相比,第一次执行查询所需的时间要长得多(约 28 秒),即使在刷新(所有索引和数据块来自)缓冲区缓存时也是如此。

对我来说,这表明硬解析正在做一些繁重的工作。要么工作量大,要么遇到很多等待。可以对此进行调查和调整。

我想知道是否可能不存在统计信息,并且优化器在准备查询计划之前花费了大量时间收集统计信息。这是我要检查的第一件事,即在所有引用的表、索引和索引列上收集统计信息。

如果您的查询连接大量表,CBO 可能会考虑连接顺序的大量排列。

Oracle 跟踪的讨论超出了这个答案的范围,但这是下一步。

我认为您可能想要跟踪事件 10053 和 10046。

这是 Tom Kyte 的“事件 10053”讨论的链接,您可能会觉得有用:

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:63445044804318


相关的轶事:硬解析性能

几年前,我确实看到一个查询在第一次执行时以 MINUTES 为单位,随后以秒为单位执行。我们发现,第一次执行的绝大多数时间都花在了硬解析上。

这个问题查询是由一个 CrystalReports 开发人员编写的,他天真地(天真地?)加入了两个巨大的报告视图。

其中一个视图是 62 个表的连接,另一个视图是 42 个表的连接。

该查询使用了基于成本的优化器。跟踪显示这不是等待时间,而是所有 CPU 时间都花在评估可能的连接路径上。

每个供应商提供的“报告”视图本身并不算太糟糕,但是当它们中的两个加入时,速度慢得令人痛苦。我相信问题在于优化器正在考虑的大量连接排列。有一个实例参数限制优化器考虑的排列数量,但我们的修复是重新编写查询。改进后的查询只加入了查询实际需要的十几个表。

(最初的短期“创可贴”修复是安排在早上早些时候运行查询,在报告生成任务运行之前。这使得报告生成“更快”,因为报告生成运行利用了已经在共享池中准备好语句,避免硬解析。

创可贴修复不是真正的解决方案,它只是将问题转移到查询的初步执行,而没有注意到长执行时间。

我们的下一步可能是为查询实现“存储大纲”,以获得稳定的查询计划。

当然,语句重用(避免硬解析,使用绑定变量)是 Oracle 中的规范模式。它提高了性能,可扩展性,yada,yada,yada。

这个轶事事件可能与您观察到的问题完全不同。


高温高压

于 2009-05-27T19:13:03.533 回答
17

自从我使用 Oracle 以来已经有一段时间了,但我相信执行计划缓存在共享池中。尝试这个:

alter system flush shared_pool;

缓冲区缓存是 Oracle 存储最近使用的数据以最小化磁盘 io 的地方。

于 2009-05-13T16:21:02.463 回答
1

我们最近在性能调优查询方面做了很多工作,导致查询性能不一致的罪魁祸首之一是 Oracle 所在的文件系统缓存。

当您刷新 Oracle 缓存时,文件系统可能仍然有您的查询要求的数据,这意味着查询仍将快速返回。

不幸的是,我不知道如何清除文件系统缓存 - 我只是使用我们非常有用的系统管理员提供的一个非常有用的脚本。

于 2009-07-17T14:14:58.720 回答