【问题标题】:My query runs faster the second time around, how do i stop that?我的查询第二次运行得更快,我该如何阻止它?
【发布时间】:2011-09-30 12:26:17
【问题描述】:

我正在 oracle 10 select A from B where C = D 中运行查询 B有数百万条记录,C上没有索引

第一次运行大约需要 30 秒,第二次运行查询大约需要 1 秒。

显然它正在缓存一些东西,我希望它停止它,每次我运行查询时我希望它花费 30 秒 - 就像它第一次运行一样。

  • 为了使问题易于阅读,我过度简化了我遇到的问题。

谢谢

【问题讨论】:

  • 您介意解释一下为什么您希望它持续缓慢运行吗?
  • 可能的答案:性能调整和测试
  • 如何强制进行硬解析:oracle-randolf.blogspot.com/2009/02/…
  • 我需要一种一致的方法来测试我创建的索引是否有任何好处,如果我的查询不花费相同的时间来运行相同的数据集,那么就很难做到科学。

标签: sql oracle indexing


【解决方案1】:

清除缓存来衡量性能是可能的,但非常笨拙。

一个非常好的跟踪调优工作性能的方法是在查询执行期间计算读取块的数量。最简单的方法之一是使用带有自动跟踪功能的 sqlplus,如下所示:

set autotrace traceonly
<your query>

输出

...
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          1  consistent gets
          0  physical reads
          0  redo size
        363  bytes sent via SQL*Net to client
        364  bytes received via SQL*Net from client
          4  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

从缓存或磁盘读取的块数为consistent gets

另一种方法是使用增加的统计信息运行查询,即使用提示 gather_plan_statistics,然后从游标缓存中查看查询计划:

auto autotrace off
set serveroutput off
<your query with hint gather_plan_statistics>
select * from table(dbms_xplan.display_cursor(null,null,'typical allstats'));

读取的块数在buffers列中输出。

---------------------------------------------------------------------------------------------------------------------
| Id  | Operation        | Name           | Starts | E-Rows | Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
---------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |                |      3 |        |     1 (100)|          |      3 |00:00:00.01 |       3 |
|   1 |  SORT AGGREGATE  |                |      3 |      1 |            |          |      3 |00:00:00.01 |       3 |
|   2 |   INDEX FULL SCAN| ABCDEF         |      3 |    176 |     1   (0)| 00:00:01 |    528 |00:00:00.01 |       3 |
---------------------------------------------------------------------------------------------------------------------

【讨论】:

  • 很有趣,但我在分析函数中使用的列上创建了一个复合索引,我想看看这个索引是否有效以及效果如何。我可以用你描述的这个效果吗?谢谢
  • 是的,查询计划的每个部分都将显示其相关成本。如果没有意外发生,这包括您的复合索引。一个意想不到的事情可能是你的索引没有被使用。
【解决方案2】:

看到这个question...

它展示了如何清除数据和执行计划的缓存,还扩展了它是否是一个好主意。

【讨论】:

    【解决方案3】:

    显而易见的答案是每个测试用例多次运行查询,并丢弃第一个结果。

    完全复制第一次查询运行的条件并不容易,因为涉及到各种缓存:一些是 Oracle 缓存(游标、缓冲区等);有些是操作系统(磁盘缓存,取决于 Oracle 配置);有些是硬件(SAN、RAID、磁盘)。

    在每次试验之前重新启动数据库服务器可能会非常接近一致的条件。

    【讨论】:

    • 第一个结果不是最准确的吗?
    • 其实第一个结果不是最不准确吗?如果你运行它 100 次,第一次也是 30 秒,其余的是 1 秒,我认为——就用户体验而言——那个 30 秒的值是相当不准确的。
    【解决方案4】:

    也许对你有帮助

    http://www.mssqltips.com/tip.asp?tip=1360

    检查点;
    去 DBCC DROPCLEANBUFFERS;
    去吧

    【讨论】:

    • EXEC sys.sp_configure N'max server memory (MB)', N'2147483646' GO RECONFIGURE WITH OVERRIDE GO(大小由你决定)
    • 错误的数据库...在 Oracle 上对 OP 没有太大帮助。 (看问题上的标签)
    猜你喜欢
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    • 2021-11-11
    • 2023-03-05
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    • 2011-09-25
    相关资源
    最近更新 更多