我有一个包含几千个不同cf-query标签的大型应用程序,因此需要一个可以轻松扩展的解决方案。我最近遇到了一个问题,我们需要在.cfc中收集所有查询的运行时间。我希望将查询时间保存到Request.queryTime
,并尝试制作一个看起来像这样的自定义标记。
<cfquery name="the_query" datasource="#Attributes.datasource#" result="thisResult">
#thisTag.GeneratedContent#
</cfquery>
<cfset Request.queryTime = Request.queryTime + thisResult.ExecutionTime />
<cfset Caller['#Attributes.name'] = Duplicate('the_query') />
当我用这个新的自定义标记替换cfquery时,它适用于某些查询,但包含
的查询<cfqueryparam>
返回以下错误。
Context validation error for tag cfqueryparam. The tag must be nested inside a cfquery tag.
我还研究过制作添加
的功能Request.queryTime = Request.queryTime + queryName.ExecutionTime
但遗憾的是,这需要知道查询名称,并且需要为所有查询添加名称。
如果有人有任何建议值得赞赏。
答案 0 :(得分:1)
首先,我想说如果你想要扩展数据调用,如果你使用内联查询,特别是那些select
列或where
语句有条件地改变的那些,你最好转换它们到存储过程。不要使用动态SQL,找出单个查询的变体并为每个变体编写一个proc。另外,为insert
,update
和delete
编写单独的proc,然后使用应用程序代码来确定调用哪个而不是在proc中做出决定。
其次,我不认为这种方法会以你想象的方式给你你想要的日期。您最好使用TestBox之类的测试框架来单独调用查询或根据需要进行分组并记录处理时间。然后,您可以在jMeter等负载测试工具下运行,以查看它在并发请求下的执行情况。
最后,如果您想了解代码和查询在各种环境或生产环境中的运行方式,请查看Fusion Reactor。这将使您深入了解瓶颈,包括发送到慢速运行查询的参数。它会保存收集的数据的历史记录,因此您可以将它们作为代码更改进行比较。
答案 1 :(得分:1)
让自己成为cf_query和cf_queryparam自定义标记集。 cf_queryparam应记住其属性的数据,然后输出唯一标记。然后,您的结束cf_query标记可以将其转换为带有cfqueryparam标记的cfquery,跟踪运行时间并返回结果。
关键是在cf_queryparam中使用cfassociate使数据可用于cf_query。
我有一个自定义标记集,可以完成所有这些(除了时间跟踪部分,但看起来你已经解决了这个问题)在私人仓库上,但我可以将它发布到可访问的地方,如果这会有所帮助。
在我的工作中,我创建了一个数组,每个键都是一串SQL或一个表示cfqueryparam的结构。然后在cfquery标记内循环遍历该数组非常容易。到目前为止,在我的测试中,这实际上非常快。
完成后,在单个提交中完成cfquery到cf_query的全局查找/替换应该可以帮助您启动并运行。