使用CFQUERY标记

时间:2017-08-26 21:55:51

标签: mysql coldfusion jvm cfquery

我最近开始收到此错误:

请求已超出允许的时间限制标记:CFQUERY

似乎每当Bing机器人访问我的网站时。我在5分钟内收到有关错误的系统通知。所以我会连续7到10个。该错误都指向一个查询:

    <CFQUERY DATASOURCE="#datasource#" USERNAME="#username#" PASSWORD="#password#" NAME="queryname" CACHEDWITHIN="#CreateTimeSpan(0,0,2,0)#">
    SELECT products.field1, products.field2, products.field3, products.field4, products.field5, products.field6, products.field7, products.field8, products.field9, products.field10, products.field11, company.field1, company.field2, company.field3, company.field4, company.field5, company.field6, company.field7
    FROM products JOIN company
    ON products.field1 = company.field1
        WHERE products.field12 = <cfqueryparam value = "#catd#" cfsqltype = "cf_sql_integer" maxLength = "2">
        ORDER by products.field13 DESC
    </CFQUERY>

它基本上选择了一个类别中的所有产品,并获取相关的公司信息并对其进行分页。每个类别返回的结果范围从2K到30K记录。最多有30个类别。

出现的错误如下:

The request has exceeded the allowable time limit Tag: CFQUERY  <br>The error occurred on line 152.
Query: cat=18&page=1803
The request has exceeded the allowable time limit Tag: CFQUERY  <br>The error occurred on line 152.
Query: cat=2&page=211
The request has exceeded the allowable time limit Tag: CFQUERY  <br>The error occurred on line 152.
Query: cat=7&page=691
The request has exceeded the allowable time limit Tag: CFQUERY  <br>The error occurred on line 152.
Query: cat=6&page=451
The request has exceeded the allowable time limit Tag: CFQUERY  <br>The error occurred on line 152.
Query: cat=14&page=417

这表明Bing机器人在不同的类别和页面上同时击中了网站的许多部分。

两周前我得到了

The request has exceeded the allowable time limit Tag: CFQUERY   

GC overhead limit exceeded null

所以我将JVM内存从1024增加到2048.但它可能只是暂时解决问题。两周后,“超出允许时限”的错误又回来了。

这个问题是由Bing机器人引起的,还是与我的代码,服务器内存或CF设置有关?

提前致谢。

2 个答案:

答案 0 :(得分:1)

如果您每页只显示20条记录,那么您的查询应该每次请求只返回20条记录。你宁愿拥有一个机器人索引200页,其中每页有20条记录,而不是单个页面上的触发超时,这会对你的应用程序和实时客户端整天产生性能影响。

FOUND_ROWS()的调用将返回与您的查询匹配的记录总数。您可以使用它来创建页面链接。

<cfparam name="url.p" type="numeric" default="1">
<cfset queryLimit = 20>
<cfset queryOffset = 0>
<cfif url.p GT 1>
    <cfset queryOffset = p * queryLimit>
</cfif>

<CFQUERY NAME="queryname" ...>
    SELECT 
        products.field1
        , products.field2
        , products.field3
        , products.field4
        , products.field5
        -- etc.
        , FOUND_ROWS() as total_rows
    FROM 
        products 
    INNER JOIN 
        company ON products.field1 = company.field1
    WHERE 
        products.field12 = <cfqueryparam value = "#catd#" cfsqltype = "cf_sql_integer" maxLength = "2">
    ORDER BY 
        products.field13 DESC
    LIMIT #queryLimit# 
    OFFSET #queryOffset#
</CFQUERY>

更新2017-11-07

在更好地阅读FOUND_ROWS()的文档后,我认为它与SQL Server中的相对功能类似的假设是不正确的。你需要做这样的事情。也许你可以在一个select中运行两个<cfquery>语句,但是我不确定它是否会为单个查询名称变量返回两个查询对象。

<CFQUERY NAME="queryname" ...>
    SELECT 
        SQL_CALC_FOUND_ROWS
        , products.field1
        , ...
    LIMIT #queryLimit# 
    OFFSET #queryOffset#
</CFQUERY>
<CFQUERY NAME="foundRows" ...>
    SELECT FOUND_ROWS() as totalCount;
</CFQUERY>

答案 1 :(得分:0)

这不是一个答案,但这对评论来说太长了

我正在看这个问题,它只是尖叫我,你正在撤回比你预期更多的数据。运行类似

的内容
<CFQUERY DATASOURCE="#datasource#" USERNAME="#username#" PASSWORD="#password#" NAME="queryname">
SELECT COUNT(products.field1) AS productCount
FROM products JOIN company
ON products.field1 = company.field1
    WHERE products.field12 = <cfqueryparam value = "#catd#" cfsqltype = "cf_sql_integer" maxLength = "2">
    ORDER by products.field13 DESC
</CFQUERY>

查看您是否获得了太多行。我尝试将行数保持在1000以下,尽管我在页面上做了多达3000次。

第二个想法

在数据库上运行缺少的索引查询。确保您已正确编入索引。

第三个想法

当我看到

products.field1, products.field2, products.field3, products.field4, products.field5, products.field6, products.field7, products.field8, products.field9, products.field10, products.field11, company.field1, company.field2, company.field3, company.field4, company.field5, company.field6, company.field7

我不喜欢所有这些专栏。如果您确实必须将其返回到HTML表格中,请在MySQL上进行字符串构建。通常不利于SQL构建HTML,但也许这是其中之一。