Performance 查询的ColdFusion查询速度比数据库调用本身慢100倍(记录计数相对较低)

Performance 查询的ColdFusion查询速度比数据库调用本身慢100倍(记录计数相对较低),performance,coldfusion,report,Performance,Coldfusion,Report,我们有一个分析图表,它首先查询数据库日志表,从优化的查询中提取所有相关信息,只选择需要的信息,同时获取相关的开始和结束ID,因为该表有数百万条记录。拉取初始查询后,我们使用ColdFusion的查询查询来处理该数据以显示不同的图表 在本例中,您可以看到实际的外部数据库调用在31ms内捕获2240条记录: qryGetLogs (Datasource=ourDSN, Time=31ms, Records=2204) 我们有一个图表,显示一周中每一天每小时的视图,然后构建一个jQuery图表来显

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

在本例中,您可以看到实际的外部数据库调用在31ms内捕获2240条记录:

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

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

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)
您可以看到,另一个查询的查询耗时4312ms,正在搜索一个包含2240条记录的查询。以下是许多后续查询的查询时间:

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秒的加载时间!但请注意,下一个查询的记录数仅为78ms,比上一个查询的记录数都多,而且在这之后,时间会更好:

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)
那些日子过得很开心,然后砰!回到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正在稳定地使用它

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


谢谢您的帮助。

我觉得您好像看到JVM垃圾收集器在工作。一种选择是尝试运行JVM监视工具,以帮助根据您的特定需求调整JVM。另一种选择是在数据库上运行子查询,而不是使用查询查询。

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

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


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

通常,查询速度非常快。然而,当数量增加时,有时可能需要更长的时间。由于您在ColdFusion文档推荐的5000到50000行范围内,所以这只能是一件事。其中一些数据正在被转换以获得结果。在本例中,是您指定的日期时间。时间值有一个前导零。我知道这听起来很奇怪

更改: 其中(CreatedOn位于“2012-09-03 0:00:00”和“2012-09-03 0:59:59”之间)

至: 其中(CreatedOn位于“2012-09-03 00:00:00”和“2012-09-03 00:59:59”之间)


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

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

但如何使用:

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

这可能和查询查询一样好。

您真的需要循环吗?理想情况下,您应该在db查询中构建结果集,因为成熟的数据库通常比QoQ的查询效率更高。在不了解更多信息的情况下,这听起来似乎可以在单个查询中完成。同意-甚至可以简单地从数据库检索数据,循环数据集,并填充结构(将是结构的结构)。在这里使用QoQ似乎不合适。谢谢你的提示!这似乎解决了性能问题。我们在1到24之间循环,1位数的小时部分没有一个前导0,加上前导0似乎让世界变得完全不同了。@ArMan-哇,如果这是真的,这就是为什么在查询中总是使用日期对象而不是字符串的一个很好的例子。虽然一个真正的数据库可以更好地优化该语句的执行,但隐式转换仍然是“…就像一盒巧克力,你永远不知道你会得到什么”——)嘿,我们确实在服务器上运行FusionReactor,到目前为止,似乎是日期格式,没有前导0。使用日期对象代替字符串。那么格式从来都不是问题。天哪,我不得不发自内心地不同意。Q of Q是提高性能的一个很好的工具。如果有一个配置正确的CF服务器,我很少(如果有的话)通过将Q代码中的Q代码推送到DB来获得性能,我希望看到一些这样的例子。我只在不得不处理优化不佳或数据库不足的问题时才使用过QoQ。正确配置的数据库将始终执行以下操作: