2011-11-25 47 views
3

我已經設置了一個查詢運行很多次的緩存..查詢本身並不是那麼慢,但它得到運行多次爲每個請求,所以計算緩存可能會有所幫助。我已啓用緩存,但似乎並沒有真正改變。如何判斷我的查詢是否被緩存?如何判斷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'} 

提前很多感謝..

Jason

EDIT AFTER Shawn的回答以下

有更改的查詢水面浮油的以下兩行: 查詢名稱現在是不同查詢不同..從傳遞PARAMATERS動態創建在

q.setName("check#arguments.room_id##DateFormat(arguments.date,'ddmmyy')#"); 

createTimeSpan除去來自引號,所以不會以字符串形式傳入。

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

我也試圖通過毫無準備的查詢發送(不使用addparam(),但只是使變量直接在查詢字符串),但並沒有區別..

EDIT 2肖恩的AFTER第三名EDITANWSER下面 肖恩..很好的皮卡編輯3!你已經隔離了問題所在。 (任何人讀這篇文章,快速,投了肖恩的答案,他發現在乾草堆中的針)

傳遞的日期作爲PARAMS不cache..eg。

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"); 

剛好路過它作爲一個變量不cache..eg。

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"); 

硬編碼的日期DOES cache..eg。

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 ..將繼續播放並查看我能找到的內容。

謝謝肖恩指出問題!

+0

您是否驗證過在ColdFusion管理器中啓用了查詢緩存,並且緩存查詢的最大數量未設置爲零? –

+0

嗨cfvonner,最大數量的緩存查詢設置爲100.我找不到可以啓用/禁用查詢緩存的位置。 – Jason

+0

它們是一個,它們相同;將該值設置爲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. 如果使用,則用戶名&的密碼必須相同。
  5. DBTYPE必須相同。

所有這些屬性在調用之前都必須保持不變,以便ColdFusion將其視爲可緩存的查詢。你在上面提到你嘗試了addParam()調用,但仍然沒有運氣...

...嘗試使用靜態查詢名稱,而不是一個變量 - 看看你是否有任何進一步的

q.setName("checkTestQuery"); 

- 第二編輯 -

另一個經常被忽視的問題是ColdFusion服務器的時鐘。確保CFServer的日期/時間設置正確。這可能聽起來很愚蠢,但我看到很多「生產」服務器的時鐘完全關閉,並且沒有設置到正確的時區,更不用說時間了......當然,時間在下列情況下具有重要意義:緩存。

- 3編輯 -

重新閱讀和審查的一切後,我會建議你多一個看看第二點我上面關於SQL語句需要是相同的製作,和您的WHERE子句依賴於受日期/時間影響的變量,這些變量可能會在每個請求上隱含變化。

...並且,由於SQL語句必須保持相同才能被緩存,所以CF會放棄對其進行緩存的任何嘗試。

嘗試暫時重構SQL語句,而不使用WHERE子句查找這些日期變量......並查看它產生的內容。

+0

謝謝肖恩,很好的皮卡。已經做了這個改變(見我原來的帖子中的編輯),但仍然沒有得到'緩存查詢'在我的調試輸出,如你所示.. – Jason

+0

添加進一步的查詢緩存清除信息,這可能有所幫助。 –

+0

肖恩,在日期上的不錯的皮卡..這是問題的地方..如果我作爲變量傳遞日期,它不會緩存..請參閱原始帖子中的編輯2。感謝您的指點!非常感謝! – Jason

1

Shawn的建議基本上是好的,但檢查查詢是否被緩存的最簡單方法是更新底層數據並查看重新查詢是否爲您提供先前緩存的數據或反映更新。如果它反映了更新,那麼它不會被緩存......

請注意,您不需要使用查詢名稱(根據您的更新)。當參數不同時,CF會自行解決,並緩存單獨的結果集。

+0

謝謝亞當,是的,肖恩已經很好地指出了問題(請參閱我的編輯2)原來的帖子..是的,停止周圍的查詢名稱horsing現在回到單個靜態查詢名稱..謝謝你指出這一點..乾杯! – Jason

相關問題