【问题标题】:ColdFusion Query of Queries 100 x Slower than the Database Call Itself (with relatively low record counts)ColdFusion 查询比数据库调用本身慢 100 倍(记录数相对较低)
【发布时间】:2012-09-05 22:48:01
【问题描述】:

我们有一个分析图表,它首先查询数据库日志表以从优化查询中提取所有相关信息,只选择需要的内容以及获取相关的开始和结束 ID,因为该表有数百万条记录。一旦提取了初始查询,我们就使用 ColdFusion 的查询查询来处理该数据以显示不同的图表。

你可以看到这个例子中实际的外部数据库调用在 31 毫秒内抓取了 2240 条记录:

qryGetLogs (Datasource=ourDSN, Time=31ms, Records=2204) 

我们有一个图表,显示一周中每一天的每小时视图,然后构建一个 jQuery 图表来显示它们。从最初的设计来看,这些查询的执行时间几乎可以忽略不计,通常为 0 毫秒。因为我们每周 7 天在一天 (24) 中的每个小时循环,即 168 次查询 - 这是不多次进行外部数据库调用的主要原因之一。

现在看来,这些查询中的许多(但不是全部)查询的运行时间是初始数据库调用的 100 倍以上。他们中的大多数都使用 BETWEEN 日期范围函数来选择每天和每小时部分的记录:

qryViewsPerHour (Datasource=, Time=4312ms, Records=5)
SELECT createdOn, DayOfWeek
FROM qryGetLogs
WHERE  (CreatedOn BETWEEN '2012-09-03 0:00:00' AND '2012-09-03 0:59:59')
AND (DayOfWeek = 2)

您可以看到另一个查询的查询花费了 4,312 毫秒,并且正在搜索具有 2,240 条记录的查询。以下是许多后续查询的查询时间:

qryViewsPerHour (Datasource=, Time=4610ms, Records=5)
qryViewsPerHour (Datasource=, Time=4187ms, Records=8)
qryViewsPerHour (Datasource=, Time=5062ms, Records=6)
qryViewsPerHour (Datasource=, Time=3985ms, Records=0)
qryViewsPerHour (Datasource=, Time=4828ms, Records=2)
qryViewsPerHour (Datasource=, Time=5750ms, Records=0)
qryViewsPerHour (Datasource=, Time=3016ms, Records=4)
qryViewsPerHour (Datasource=, Time=3625ms, Records=6)
qryViewsPerHour (Datasource=, Time=6265ms, Records=11)

所以你可以通过这些查询看到,它增加了 40 秒的加载时间!但请注意,下一个查询只有 78 毫秒,记录比之前的任何一个查询都多,而且在此之后,时间会更好:

qryViewsPerHour (Datasource=, Time=78ms, Records=18)
qryViewsPerHour (Datasource=, Time=62ms, Records=7)
qryViewsPerHour (Datasource=, Time=63ms, Records=12)
qryViewsPerHour (Datasource=, Time=78ms, Records=34)
qryViewsPerHour (Datasource=, Time=78ms, Records=9)

那些美好的时光会持续一段时间,然后 BAM!回到 2-6 秒的查询。

qryViewsPerHour (Datasource=, Time=4891ms, Records=13)
qryViewsPerHour (Datasource=, Time=1984ms, Records=8)
qryViewsPerHour (Datasource=, Time=4875ms, Records=4)
qryViewsPerHour (Datasource=, Time=6203ms, Records=0)

总而言之,加载需要几秒钟的内容需要 100-400 秒之间的加载,这只是每周报告!我们还将它用于月度报告。

我已经监控了服务器,确保我是唯一一个运行请求的人或进程,所以不应该是CPU的资源被其他东西吃掉了,我也监控了CPU请求,它很稳定并且稳定被 JRUN.exe 使用。

有人对这个问题有什么建议吗?快把我逼疯了!

感谢您的帮助。

【问题讨论】:

  • 你真的需要循环吗?理想情况下,您应该在 db 查询 中构建结果集,因为成熟的数据库在查询方面通常比 QoQ 更有效。在不了解更多信息的情况下,听起来这当然可以在单个查询中完成。
  • 同意 - 甚至可以简单地从数据库中检索数据,遍历数据集,并填充一个结构(将是一个结构的结构)。在这里使用 QoQ 似乎不合适。

标签: performance coldfusion report


【解决方案1】:

通常,查询的查询速度非常快。但是,有时当交易量增加时可能需要更长的时间。由于您在 ColdFusion 文档推荐的 5,000 到 50,000 行推荐范围内,它只能是一回事。有些地方正在翻译一些数据以获得结果。在这种情况下,它是您指定的日期时间。时间值有一个前导零。我知道这听起来很奇怪。

更改: WHERE(在 '2012-09-03 0:00:00' 和 '2012-09-03 0:59:59' 之间创建)

收件人: WHERE(在 '2012-09-03 00:00:00' 和 '2012-09-03 00:59:59' 之间创建)

我对此进行了测试,发现结果更好。

【讨论】:

  • 感谢您的提示!这似乎解决了性能问题。我们在 1 到 24 之间循环,1 位数字的小时部分没有前导 0,并且添加前导 0 似乎使世界变得与众不同。
  • @ArMan - 哇,如果这是真的,这是一个很好的例子,说明为什么你应该总是在查询中使用日期 objects字符串。虽然真正的数据库会更好地优化该语句的执行,但隐式转换仍然“......就像一盒巧克力。你永远不知道你会得到什么”;-)
【解决方案2】:

虽然根据我的经验,Coldfusion 具有执行查询查询的功能,但它是最后的手段。原因是它是多么低效和有限。 CF 是一种编程语言,而不是 SQL 语言,因此它没有任何真正的 DB 所具有的优化功能。

我强烈建议将查询推送到数据库中,如果您有一个支持视图的数据库,我还建议您根据原始查询创建一个视图,这样您只需对视图执行子查询,而不是整个原始查询表。

尽可能避免查询查询,尤其是在处理大型数据集时,因为它必须全部作为大量 Java 对象存储在内存中。正如 Russ 所指出的,它会受到垃圾收集器的影响,并且随着您的报告的增长,可能会导致内存不足的问题。 (我曾经用过大的 QoQ 把我的电脑弄翻了)

【讨论】:

  • 男孩,我不得不由衷地反对。 Q of Q 可以成为提高性能的好工具。给定一个正确配置的 CF 服务器,我很少(如果有的话)通过将 Q 的 Q 代码推送到数据库来获得性能,并且希望看到一些例子。
  • 当我不得不解决优化不佳或数据库不足的问题时,我才使用过 QoQ。一个正确配置的数据库总是会比 CF 执行得更好(在查询的基础上),因为它是构建它的目的。然而,我离题了,我只在 CFML 上工作了一年半,还有很多要了解的细节或优化。
  • 我倾向于同意 Dpolehonski。数据库在查询方面要好得多。但是,由于网络流量,它们也会产生额外的开销。内存查询不需要,但它们比典型的数据库查询需要更多的 CF 内存资源。所以这是一个平衡。 QoQ 确实有一席之地,但 IMO 他们经常过度使用或误用。通常,精心设计的数据库查询会执行得更好。
  • .. 在正常情况下,您的平均数据库可以在单个查询中计算这些每小时/每周/每年的总数。使用适当的索引,它会比等效的循环代码更快、更有效——即使使用 QoQ 也是如此。循环总是减慢速度。因此,只要有可能,就应该在数据库中完成繁重的数据提升,因为它专门针对该工作进行了优化。当然,有时由于其他限制是不可能的。这里可能就是这种情况。但是,循环和 QoQ 不应该是“第一”选择。
【解决方案3】:

在我看来,您正在看到 JVM 垃圾收集器在工作。一种选择是尝试运行 JVM 监控工具,以帮助调整 JVM 以满足您的特定需求。另一种选择是在数据库上运行子查询,而不是查询查询。

【讨论】:

  • 嘿,我们确实在服务器上运行了 FusionReactor,到目前为止,它似乎是日期格式,并且没有前导 0。
  • 使用日期对象代替字符串。那么格式化就不是问题了。
【解决方案4】:

我很高兴你发帖,因为我一直认为这比往返服务器要好。

但是如何使用:

cachedWithin="#CreateTimeSpan(0,0,1,0)#"

这可能和查询一样好。

【讨论】:

    猜你喜欢
    • 2021-04-03
    • 2015-05-23
    • 2011-07-30
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 2021-05-27
    • 2019-08-18
    • 2012-06-05
    相关资源
    最近更新 更多