首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >加速QoQ还是另一种方法?

加速QoQ还是另一种方法?
EN

Stack Overflow用户
提问于 2011-05-05 23:43:01
回答 3查看 275关注 0票数 2

我正在构建一个应用程序,该应用程序执行具有多个连接的主查询。然后,整个应用程序都可以在全局变量中处理这些查询数据。查询在每次页面刷新时刷新或获取最新的结果集;因此,它只在请求的生命周期内处于相同的状态。

在这个应用程序的其他部分,我有时会对这些数据运行100个QoQ--通常是递归函数调用的结果。然而,虽然QoQ是一个很棒的功能,但它并不太快,有时页面加载可能在糟糕的一天在3000 - 5000毫秒之间。这还不够快。

有没有什么优化技术可以让QoQ执行得更快,或者是另一种方法?我读过Ben Nadel写的一篇关于Duplicate()函数的有趣文章--它有没有用的余地,如果有,又是怎么用的?

我很想听听你的想法。

不要担心疯狂的建议,这是一个个人项目,所以我愿意冒险。我在兼容CF8的Railo上运行这个程序。

非常感谢,迈克尔。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-05-06 03:46:34

在看不到QoQ的代码和复杂性的情况下,很难说最好的方法是什么,但是您可以做的一件事是在QoQ之外使用结构来索引记录。使用QoQ的大部分开销是构建新的查询对象,并且使用结构只写方法比循环遍历原始查询和进行比较要高效得多。

例如:

代码语言:javascript
复制
<!--- build up index --->
<cfset structindex = {} />
<cfset fields = "first,last,company" />
<cfloop list="#fields#" index="field">
    <cfset key = "field:#field#,value:#q[field][currentrow]#" />
    <!--- initialize each key (instead of using stuctkeyexists) --->
    <cfloop query="q">
        <cfset structindex[key] = "" />
    </cfloop>
    <cfloop query="q">
        <!--- update each key with list of matching row indexes --->
        <cfset structindex[key] = listappend(structindex[key], currentrow) />
    </cfloop>
</cfloop>

<!--- save structindex to global variable --->

<!--- output rows matching index --->
<cfset key = "field:company,value:stackexchange" />
<cfoutput>
    <cfloop list="#structindex[key]#" index="row">
        #q.last[row]#, #q.first[row]# (#q.company[row]#)<br />
    </cfloop>
</cfoutput>

如果这不符合您的需要,请提供一些QoQ语句的示例,以及主查询中有多少条记录。

票数 2
EN

Stack Overflow用户

发布于 2011-05-06 00:06:09

首先,我将查看主查询所用的时间。如果它可以被缓存一段时间,并且占用了大量的页面加载时间,我会缓存它。

接下来,我将查看递归调用。如果它们可以进行迭代,那么可能会加快速度。我意识到这并不总是可能的。如果这不是你最大的时间槽,我会很惊讶。但是,如果不了解更多关于您正在做的事情,就很难帮助您优化它。

我还可以考虑在DB服务器上编写一些递归的QoQs存储过程,该服务器旨在快速处理数据并有效地分割数据。CF不是-- as非常有用,但不是速度问题(如您所提到的)。

最后,我会寻找简单的过滤器,而不是使用QoQ。相反,我只会在标准cfoutput标记中的主查询上运行一个循环,并动态过滤。这意味着您只需在主查询上循环一次,而不是在主查询上循环一次,在结果查询上循环一次。

票数 1
EN

Stack Overflow用户

发布于 2011-05-06 04:03:36

这里有两个主要的解决方案。首先,您可以在CF中对QoQ之外的记录执行某些操作。我已经在这上面发布了我的建议。另一种是在数据库中执行所有操作。我发现的一种方法是使用子查询作为临时表。您甚至可以将sql语句保存在一个全局变量中,然后在您当前使用QoQ但对数据库执行实际查询的相同位置引用它。这听起来可能比一次访问数据库然后访问许多QoQ要慢,但实际上,如果索引有效的话,可能并不是这样。

代码语言:javascript
复制
select *
from (
    #sqlstring#
) as tmp
where company = 'stackexchange'

我实际上已经为系统这样做了,这些系统具有复杂的标准,既有用户应该有权访问的记录,也有用户可以在这些记录中过滤的记录。使用这种方法意味着你总是知道内部记录的来源,而不是试图确保每个查询都是正确的。

编辑:如果可能的话,使用queryparams实际上更安全(通常也更有效)。我发现这可以通过包含sql语句的文件来实现。

代码语言:javascript
复制
select *
from (
    <cfinclude template="master_subquery.cfm" />
) as tmp
where company = 'stackexchange'
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5900550

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档