Как мне узнать, кэшируется ли запрос Coldfusion? - PullRequest
3 голосов
/ 25 ноября 2011

Я установил кеширование для запроса, который запускается много раз ... сам запрос не такой уж медленный, но он выполняется многократно для каждого запроса, поэтому фигурное кэширование может помочь.Я включил кеширование, но, похоже, ничего не изменилось ... как мне узнать, кэшируется ли мой запрос или нет?

Я устанавливаю кеширование с помощью: 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 ПОСЛЕ 3-го РЕДАКТИРОВАНИЯ ШОНА НИЖЕ Шон .. хороший подбор при редактировании 3 !!!Вы изолировали, где проблема.(любой, кто быстро читает ответ Шона, он нашел иголку в стоге сена)

Передача дат в качестве параметров не кешируется ... например.

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

Этовсе хорошо, но, очевидно, я не могу жестко закодировать даты ... Очевидно, что даты будут меняться для каждого дня, но даже там, где я выполняю один и тот же запрос с теми же датами, которые передаются динамически (синтаксис запроса точно такой же),запрос не будет кешироваться, если даты передаются как переменные ... только если они жестко запрограммированы в запросе ... странно .. продолжит играть и посмотрим, что я смогу найти.

Спасибо, Шон, завыявление проблемы !!!

Ответы [ 2 ]

9 голосов
/ 25 ноября 2011

Если бы он был правильно кеширован, ваши выходные данные отладки включали бы лишь небольшую часть дополнительной информации, на мелодию:

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

Что-то препятствует кешированию вашего запроса.

Я заметил, что у вашего вызова .setCachedWithin () есть строка, передаваемая ему, или, скорее, вы делаете ее строкой, квалифицируя ее кавычками и используя знаки #.

Попробуйте передать фактическое значениевозвращается из CreateTimeSpan () без преобразования его в строку, например так:

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

- edit -

Некоторые другие заметки о кэшировании запросов:

  1. Имя запроса должно быть одинаковым.
  2. Оператор SQL (во всех его параметризованных формах) должен быть одинаковым.
  3. Источник данных должен быть одинаковым.
  4. Если используется, имя пользователя и пароль должны быть одинаковыми.
  5. DBTYPE должен быть одинаковым.

Все эти атрибуты должны оставаться неизменными от вызова к вызову взаказ для ColdFusion, чтобы считать это кеш-запросом.Вы упомянули выше, что пытались убрать вызовы addParam (), но все равно не повезло ...

... попробуйте использовать статическое имя запроса, а не переменное - посмотрите, есть лидалее

q.setName("checkTestQuery");

- 2-е редактирование -

Другая часто пропускаемая проблема - это часы сервера ColdFusion.Убедитесь, что дата / время CFServer установлены правильно.Это может звучать глупо, но я видел много «производственных» серверов, часы которых были полностью выключены и не были настроены на правильный часовой пояс, не говоря уже о времени ... и время, конечно, имеет большое значение в контекстекэширование.

- 3-е редактирование -

После перечитывания и просмотра всего, я рекомендую вам еще раз взглянуть на 2-й пункт, который я сделал выше относительно оператора SQLдолжны быть такими же, и ваше предложение WHERE зависит от переменной, на которую влияют дата / время, которая неявно может меняться при каждом запросе .

... и, посколькуОператор SQL должен оставаться неизменным, чтобы его можно было кэшировать, CF отбрасывает все попытки его кэшировать.

Попробуйте временно перестроить инструкцию SQL, не используя предложение WHERE для поиска этих переменных даты ... и посмотрите, что оно выдает..

1 голос
/ 25 ноября 2011

Совет Шона в основном хорош, но самый простой способ проверить, кэшируется ли запрос, - обновить базовые данные и посмотреть, дает ли запрос ранее кэшированные (все хорошо) данные или отражает обновления. Если он отражает обновления, то он не кэшируется ...

Обратите внимание, что вам не нужно делать это с указанием имени запроса (согласно вашему обновлению). CF будет работать самостоятельно, когда параметры различаются, и кэшировать отдельные наборы результатов.

...