2010-04-10 2 views
4

49403459 레코드가 들어있는 테이블이 있습니다.날짜에 대한 where 절에서 to_char가있는 Oracle 쿼리를 최적화하는 방법

날짜 범위의 테이블을 쿼리하고 싶습니다. 04/10/2010 ~ 04/10/2010이라고 말하십시오. 그러나 날짜는 10-APR-10 10.15.06.000000 AM (시간 소인) 형식으로 표에 저장됩니다. 내가

SELECT bunch,of,stuff,create_date 
FROM myTable 
WHERE TO_CHAR (create_date,'MM/DD/YYYY)' >= '04/10/2010' 
AND TO_CHAR (create_date, 'MM/DD/YYYY' <= '04/10/2010' 

내가 529 행을 얻을 수 있지만, 255.59 초에 할 결과

! 내가 각 레코드에서 TO_CHAR을하고 있다고 생각하기 때문입니다.

그러나, 나는

SELECT bunch,of,stuff,create_date 
FROM myTable 
WHERE create_date >= to_date('04/10/2010','MM/DD/YYYY') 
AND create_date <= to_date('04/10/2010','MM/DD/YYYY') 

을 수행 할 때 그때 0.14초에서 0 결과를 얻을 수 있습니다.

어떻게하면이 쿼리를 빠르게 만들 수 있으며 유효한 결과 (529)를 얻을 수 있습니까?

이 시점에서 색인을 변경할 수 없습니다. 지금은 색인이 create_date 열에 생성 된 것 같습니다.

두 날짜 범위를 변환하여 첫 번째 날짜 범위가 모두 0 인 타임 스탬프로 변환되고 두 번째 날짜가 날짜의 마지막 타임 스탬프 인 타임 스탬프로 변환되도록하려면 어떻게해야합니까? 그 말이 맞는다면 ...?

중 절은 어떤 결과를 가져옵니다 없습니다 다음 첫 번째 쿼리에서

WHERE    
create_date >= to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 
AND 
create_date <= to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 

답변

2

, 당신은 문자 비교보다는 올바른 결과를 생산하지 않아야 날짜 비교를하고 있습니다. 하루 구성 요소 '02은'비교 문자 올해 평가되지 않습니다 하루 구성 요소 '01'보다 더 크기 때문에

예를 들어, 논리를 사용하여, 01/02/2009보다 큰 01/01/2010 될 것입니다.

+0

감사합니다. 나는 그것을 시도했다. 그러나 아직도 나는 어떤 결과도 얻지 않는다. 내 편집을 참조하십시오 – Josh

+0

내 대답을 편집했습니다. 귀하의 두 번째 쿼리가 아마도 정확하다고 생각합니다. 첫 번째 쿼리는 잘못된 결과를 제공합니다. – newdayrising

+0

아니요 ... 테이블을 쿼리하여 오늘 만들어진 레코드가 있는지 확인할 수 있습니다. .. – Josh

2

이 작동 :

WHERE    
create_date >= to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 
AND 
create_date <= to_timestamp('04/10/2010 23:59:59:123000','MM/DD/YYYY HH24:MI:SS.FF') 
1
SELECT bunch,of,stuff,create_date 
    FROM myTable 
WHERE create_date >= to_date('04/10/2010','MM/DD/YYYY') 
    AND create_date < to_date('04/11/2010','MM/DD/YYYY') 

04/10/2010은 11시 59 분 59 초 시까 지 10 일 자정부터 모든 날짜 값이 포함 된 날짜, 그래서 11 이하의 모든 것을 얻는 것 모든 기지를 덮어 라. 다른 방법으로는 myTable의 데이터에 데이터 항목에서 잘린 CREATE_DATE 필드가 있는지 확인하는 것입니다. 나는 DATE 필드를 위해 그렇게하는 것을 선호하며, 시간 구성 요소를 신경 쓰면 TIMESTAMP를 사용합니다. 물론

3

이 작동하지 않습니다

WHERE    
    create_date >= to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 
AND 
    create_date <= to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 

을 create_date 정확히 2010년 4월 10일 오전 12시 어디 그 행만 반환하기 때문에!

WHERE    
    create_date >= to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 
AND 
    create_date < to_timestamp('04/11/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 

을 또는 당신이 선호하는 경우 : 당신이 create_date이 2010년 4월 10일의 날에 언제든지 발생하는 모든 행을 얻고 싶은 경우에

이를 사용하여

WHERE create_date BETWEEN to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 
         AND to_timestamp('04/10/2010 23:59:59.999999','MM/DD/YYYY HH24:MI:SS.FF') 

네가 자정을 나타 내기를 원하면 다른 모든 부분을 나간다. 그래서 당신은 말할 수 :

WHERE    
    create_date >= to_timestamp('04/10/2010','MM/DD/YYYY') 
AND 
    create_date < to_timestamp('04/11/2010','MM/DD/YYYY') 
4

내가 529 개 행을 얻을 수 있지만, 255.59 초! 각 레코드마다 TO_CHAR을 (를)하고 있기 때문에 어느 것입니까? 첫 번째 쿼리에 대해 generate an execution plan에 있다면

...

explain plan for 
SELECT bunch,of,stuff,create_date 
FROM myTable 
WHERE TO_CHAR (create_date,'MM/DD/YYYY)' >= '04/10/2010' 
AND TO_CHAR (create_date, 'MM/DD/YYYY') <= '04/10/2010' 
/

... 당신은 전체 테이블 스캔을한다는 것을 볼 것입니다. to_char()이 CREATE DATE에서 색인의 사용을 금지하기 때문입니다.

당신은 당신이 실행했을 때 결과를 반환하는 데 걸린 시간을 말을하지 않습니다

...

SELECT bunch,of,stuff,create_date 
FROM myTable 
WHERE    
create_date >= to_timestamp('04/10/2010 00:00:00.000000','MM/DD/YYYY HH24:MI:SS.FF') 
AND 
create_date <= to_timestamp('04/10/2010 23:59:59:123000','MM/DD/YYYY HH24:MI:SS.FF') 
/

...하지만 나는 그것이 4 분 이상 0.14 초 방법 가까웠다 기대합니다.

0

첫 번째 쿼리가 잘못된 결과와 문자열 비교를하고 있습니다. 귀하의 두번째 쿼리는 할 필요가 :

WHERE create_date> = TRUNC (TO_DATE ('04/10분의 2,010 ','MM/DD/YYYY '))

또는 HH를 추가 : mi : 술어에 대한 ss. 오라클이 기대하는 것과 다른 방식으로 날짜를 포매팅한다고해서 단순히 작동하지 않습니다.

관련 문제