2011-11-25 2 views
3

많은 시간 동안 실행되는 쿼리에서 캐싱을 설정했습니다. 쿼리 자체가 느린 것은 아니지만 각 요청마다 여러 번 실행되므로 계산 된 캐싱이 도움이 될 수 있습니다. 나는 캐싱을 가능하게했지만 실제로는 차이를 내지 않는 것처럼 보입니다. 내 쿼리가 캐싱되고 있는지 여부를 어떻게 알 수 있습니까? q.setCachedWithin("#createTimespan(0, 1, 0, 0)#"); 여기Coldfusion 쿼리가 캐싱 중인지 어떻게 알 수 있습니까?

내 전체 쿼리는 Preperation됩니다 :

  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

편집

아래 숀의 대답이 쿼리는 Preperation 다음 두 줄의 변경 후 :

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

createTimeSpan에 쿼리 이름은 쿼리를 다른 이제 다른 .. 통과 PARAMATERS에서 동적으로 생성을 제거 따옴표로 묶어 문자열로 전달하지 않습니다.

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

는 또한 (addparam()를 사용하지만, 단지 바로 쿼리 문자열의 변수 렌더링되지 않음) 준비가 쿼리를 전송했지만, 숀 후에 차이 ..

2 편집을하지 않은 3rd EDITANWSER BELOW Shawn .. 편집에 좋은 픽업 3 !!! 문제가있는 곳을 격리했습니다. cache..eg하지 않는 PARAMS로 날짜를 전달

(이 글을 읽는 사람이, 빠른, 최대 숀의 답변을 투표, 그는 건초 더미에서 바늘을 발견).

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

하지만 하드 날짜를 않습니다 코딩 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 .. 계속 재생하고 찾을 수있는 부분을 봅니다.

문제를 정확히 지적 해 주셔서 감사합니다.

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

뭔가가 캐시되는 쿼리를 방지한다 : 올바르게 캐시 된 경우

+0

ColdFusion Administrator에서 쿼리 캐시가 활성화되어 있고 캐시 된 쿼리의 최대 수가 0으로 설정되지 않았는지 확인 했습니까? –

+0

안녕하세요 cfvonner, 캐시 된 쿼리의 최대 수는 100으로 설정됩니다. 쿼리 캐시를 활성화/비활성화 할 수있는 위치를 찾을 수 없습니다. – Jason

+0

이들은 하나이며 동일합니다. 값을 0으로 설정하면 쿼리 캐싱이 비활성화됩니다. –

답변

9

, 디버그 출력의 조정에 대한 추가 정보의 단지 작은 비트를 포함 할 것이다.

.setCachedWithin()에 전달 된 문자열이 있습니다. 또는 따옴표로 묶고 # 기호를 사용하여 문자열로 지정하는 것입니다.

과 같이, 문자열로 변환하지 않고, CreateTimeSpan()에서 반환 된 실제 값을 전달하십시오 :

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

- 편집 - 쿼리 캐싱에 대해주의 할

일부 다른 맛있는 가벼운 음식 :

  1. 쿼리 이름은 같아야합니다.
  2. SQL 문 (모든 매개 변수가있는 형식)은 동일해야합니다.
  3. 데이터 소스가 동일해야합니다.
  4. 사용하는 경우 사용자 이름 &은 동일해야합니다.
  5. DBTYPE은 동일해야합니다.

이러한 모든 속성은 ColdFusion에서 캐시 가능 쿼리로 간주하기 위해 호출 간 호출에서 동일하게 유지되어야합니다. 위에서 언급 한 addParam() 호출을 시도했지만 여전히 운이 없었습니다.

... 변수가 아닌 정적 쿼리 이름을 사용하십시오. 더 이상 얻을 수 있는지 확인하십시오.

q.setName("checkTestQuery"); 

- 2 편집 -

또 다른 종종 간과 문제는 ColdFusion 서버의 시계입니다. CFServer의 날짜/시간이 올바르게 설정되었는지 확인하십시오. 어리석게 들릴지 모르지만 시계가 완전히 꺼져 있고 정확한 시간대로 설정되지 않은 많은 "프로덕션"서버를 보았습니다. 물론 시간은 말할 것도 없습니다 ... 물론 시간은 물론 맥락에서 큰 의미가 있습니다. 캐싱.

- 3 편집 -

다시 읽기 및 검토 모든 후, 난 당신이 내가 동일하게 필요로하는 SQL 문에 대한 위의 만든 2 지점에서 한 번 더 살펴 추천하는거야, WHERE 절은 날짜/시간의 영향을받는 변수에 종속적이며 모든 요청에 ​​따라 암시 적으로 변경 될 수 있습니다..

... SQL 문이 캐싱되기 위해 동일하게 유지되어야하므로 CF는 캐쉬 시도를 무시합니다.

WHERE 절이 해당 날짜 변수를 찾지 않고 일시적으로 SQL 문을 재구성하여 ... 작성한 내용을 확인하십시오.

+0

감사합니다 숀, 좋은 픽업. 이 변경 (내 원래 게시물에서 편집 참조)을 만들었지 만 표시된대로 내 디버그 출력에 '캐시 된 쿼리'가 표시되지 않습니다. – Jason

+0

추가 쿼리 캐시 파열 정보가 도움이 될 수 있습니다. –

+0

Shawn, 날짜에 멋진 픽업 .. 문제가있는 곳입니다. 날짜를 변수로 전달하면 캐시되지 않습니다. 원래 게시물의 EDIT 2를 참조하십시오. 모든 포인터를 가져 주셔서 감사합니다 !! 정말 감사합니다! – Jason

1

Shawn의 충고는 대부분 좋지만 쿼리가 캐시되고 있는지 확인하는 가장 쉬운 방법은 기본 데이터를 업데이트하고 쿼리를 통해 이전에 캐싱 된 데이터가 있는지 또는 업데이트를 반영하는지 확인하는 것입니다. 업데이트가 반영되면 캐시되지 않습니다 ...

업데이트 이름과 일치하지 않아도됩니다. CF는 매개 변수가 다른 경우 자체적으로 작동하고 별도의 결과 집합을 캐싱합니다.

+0

Thanks Adam, 네, Shawn은 원본 게시물에서 문제 (제 2 편집 참조)를 가리키는 데 능숙합니다. 예, 이제 쿼리 이름을 사용하지 말고 단일 정적 쿼리 이름으로 돌아 왔습니다. 감사합니다. 그걸 지적 해. 건배! – Jason

관련 문제