如何判断coldfusion查询是否缓存?

时间:2011-11-25 05:33:22

标签: coldfusion

我已经在很多次运行的查询上设置了缓存..查询本身并不是那么慢,但是每次请求都会运行多次,因此有点缓存可能会有所帮助。我已经启用了缓存,但似乎没有什么区别......如何判断我的查询是否被缓存?

我正在设置缓存:q.setCachedWithin("#createTimespan(0, 1, 0, 0)#");

这是我的完整查询预备:

            q = New Query();
            q.setSQL("SELECT * FROM guest_booking WHERE room_id = :roomID and check_in <= :iDate and check_out > :iDate and status != 0");
            q.setName("checkAvailability");
            q.setCachedWithin("#createTimespan(0, 1, 0, 0)#");
            q.addParam(name="iDate", value="#createODBCDate(arguments.date)#", cfsqltype="cf_sql_date");
            q.addParam(name="roomID", value="#createODBCDate(arguments.room_id)#", cfsqltype="cf_sql_integer");
            qResult = q.execute().getresult();

调试输出显示:

checkAvailability (Datasource=accom_crm, Time=16ms, Records=1) in C:\ColdFusion9\CustomTags\com\adobe\coldfusion\base.cfc @ 16:15:56.056


                        SELECT * FROM guest_booking WHERE room_id = 

                                    ?

                                 and check_in <= 

                                    ?

                                 and check_out > 

                                    ?

                                 and status != 0

Query Parameter Value(s) -
Parameter #1(cf_sql_integer) = 56
Parameter #2(cf_sql_date) = {ts '2011-11-14 00:00:00'}
Parameter #3(cf_sql_date) = {ts '2011-11-14 00:00:00'}

非常感谢...

杰森

编辑后显示

更改了以下两行查询预处理: 对于不同的查询,查询名称现在是不同的..从

中传递的参数动态创建
q.setName("check#arguments.room_id##DateFormat(arguments.date,'ddmmyy')#");

createTimeSpan从引号中删除,因此不以字符串形式传入。

q.setCachedWithin(createTimespan(0, 1, 0, 0));

我也试过通过一个没有准备的查询发送(不使用addparam(),只是在查询字符串中直接渲染变量),但没有区别......

编辑2在SHAWN的第三个EDITANWSER之后编辑 Shawn ..在编辑3上很好的拾取!!!你已经孤立问题所在。 (任何读这篇文章的人,快速,向上投票Shawn的答案,他在干草堆中发现了一根针)

将日期作为参数传递不会缓存..例如..

q.setSQL("SELECT booking_id FROM guest_booking WHERE room_id = :roomID and check_in <= :iDate and check_out > :iDate and status != 0");
q.addParam(name="iDate", value="#createODBCDate(arguments.date)#", cfsqltype="cf_sql_date");

将其作为变量传递不会缓存..例如..

q.setSQL("SELECT booking_id FROM guest_booking WHERE room_id = :roomID and check_in <= #createODBCDate(arguments.date)# and check_out > #createODBCDate(arguments.date)# and status != 0");

但是对日期进行硬编码才能缓存..例如..

q.setSQL("SELECT booking_id FROM guest_booking WHERE room_id = :roomID and check_in <= {ts '2011-12-16 00:00:00'} and check_out > {ts '2011-12-16 00:00:00'} and status != 0");

这一切都很好,但很明显我不能对日期进行硬编码......显然每天的日期都会发生变化,但即使我运行同一个查询并且动态传递相同的日期(查询语法为完全一样),如果日期作为变量传递,查询将不会缓存..只有当它们被硬编码到查询中时... wierd ..将继续播放并查看我能找到的内容。

谢谢Shawn查明问题!!!

2 个答案:

答案 0 :(得分:9)

如果它被正确缓存,您的调试输出将只包含一小部分附加信息:

checkAvailability (Datasource=accom_crm, Time=0ms, Records=1, Cached Query) 

阻止查询被缓存。

我注意到你对.setCachedWithin()的调用有一个字符串被传递给它 - 或者说,你通过用引号限定它并使用#符号来使它成为一个字符串。

尝试传递从CreateTimeSpan()返回的实际值,而不将其转换为字符串,如下所示:

q.setCachedWithin(createTimeSpan(0, 1, 0, 0));

- 编辑 -

关于查询缓存的一些其他花絮:

  1. 查询的名称必须相同。
  2. SQL语句(所有参数化形式)必须相同。
  3. 数据源必须相同。
  4. 如果使用,用户名&amp;密码必须相同。
  5. DBTYPE必须相同。
  6. 所有这些属性必须在调用之间保持不变,以便ColdFusion将其视为可缓存的查询。你在上面提到你尝试过调用addParam(),但仍然没有运气......

    ...尝试使用静态查询名称,而不是使用变量名称 - 请参阅是否有进一步的

    q.setName("checkTestQuery");
    

    - 第二次编辑 -

    另一个经常被忽视的问题是ColdFusion服务器的时钟。确保正确设置了CFServer的日期/时间。这可能听起来很愚蠢,但我看到很多“生产”服务器的时钟完全关闭,并没有设置到正确的时区,更不用说时间......当然,时间在内容中具有重要意义。缓存。

    - 第3次编辑 -

    在重新阅读并查看所有内容之后,我建议你再看一下我上面提到的关于SQL语句需要相同的第二点,并且你的WHERE子句依赖于受日期/时间影响的变量,每个请求都可以隐式更改

    ...并且,由于SQL语句必须保持相同才能被缓存,因此CF会丢弃任何缓存它的尝试。

    尝试暂时重构SQL语句,而不使用WHERE子句查找这些日期变量......并查看它产生的内容。

答案 1 :(得分:1)

Shawn的建议大多是好的,但检查查询是否被缓存的最简单方法是更新基础数据,看看requerying是否为您提供以前缓存的(一切顺利)数据,或反映更新。如果它反映了更新,那么它不会被缓存......

请注意,您不需要使用查询名称(根据您的更新)。当参数不同时,CF将自行计算,并缓存单独的结果集。