【发布时间】:2016-01-31 11:55:49
【问题描述】:
我正在使用 cx_Oracle 模块在 Python 中进行一些数据库基准测试。为了对结果进行基准测试,我运行了 150 个唯一查询并为每个查询的执行计时。我正在运行这样的东西:
c = connection.cursor()
starttime = time.time()
c.execute('SELECT /*+ NOCACHE */ COUNT (*) AS ROWCOUNT FROM (' + sql + ')')
endtime = time.time()
runtime = endtime - starttime
每个查询都是通过变量sql 传入的,它们在长度、运行时间和它们访问的表方面有很大差异。话虽如此,所有查询都表现出以下行为:
第一次运行:非常慢(相对)
第 2 次运行: 明显更快(需要 1/2 到 1/5 的时间)
第三次运行:略快于第二次运行
所有后续运行 >= 4: 大约等于第 3 次运行
我需要禁用缓存才能获得准确的结果,但前几次运行确实会丢失我的数据;好像NOCACHE 根本不工作……这是怎么回事?
编辑:Allan 回答了我的问题,但对于任何可能感兴趣的人,我做了更多的研究,发现这两个页面也很有帮助:
【问题讨论】:
-
您希望实时系统进行缓存,因为这样可以提高性能。所以你不应该安排你的基准测试,以便丢弃每个查询的前两次运行(a.k.a.“老化”)。您在
sql有哪些疑问?您当前传入查询的方式不允许使用绑定变量,即如果查询包含输入参数,这些将嵌入到查询文字中,这将导致hard parse在每次执行之前,我认为这会导致 #1 中的滞后。 -
我有点困惑。由于我假设查询将在生产中被硬解析,因此我想要保持较慢的运行。事实上,我实际上是想让它们与第一次运行保持一致。这种情况需要不缓存的查询,因为测试是在具有不同配置的多个数据库中进行的,并且系统上的用户只会运行一次查询,这使得缓存时间对于基准测试无效。
-
好吧,我不知道您正在测试在生产环境中只会运行一次的查询。如果查询真的很繁重,那么硬解析可能不是这里最大的因素,而是查询执行速度很慢。您可以使用像 tkprof 这样的 Oracle 实用程序进行分析吗?
-
我可能会在星期一调查一下。我不是 DBA,我只是为他编写基准脚本的人。我对这些东西还很陌生,所以我还有很多东西要学!
-
@McGlothlin 需要注意的是,Oracle 不会缓存查询结果,它会缓存最常用的表和索引块。这意味着不同的查询可以利用相同的缓存。您很可能确实希望在任何 OLTP 测试中排除“老化”时间。通常
alter system flush buffer_cache;只会帮助在数据仓库中进行实际测试。不幸的是,这使您的测试变得更加困难 - 如果没有完美匹配的查询、数据和环境,就很难复制缓存行为。
标签: python oracle oracle11g cx-oracle