작성
·
112
0
1997년에 주문한 주문 정보를 추출하는 쿼리에서 날짜 조건을 아래처럼
and o.order_date = to_date('1997','yyyy')
작성하면 결과값이 안나오는데 다른 이유가 있을까요??
강의 속 코드인 between A and B 구문보다 간단하다고 생각해서 위처럼 코드를 작성했습니다.
답변 1
0
안녕하십니까,
o.order_date = to_date('1997', 'yyyy')로 하면 1997년 1월 1일 단 하루동안의 order 일자에 해당하는 것만 가져오기 때문에 결과값이 나오지 않습니다.
원하시는 대로 between이 아니고 = 로 해당 년도의 모든 데이터를 가져오려면 아래와 같이 수행하시면 됩니다.
select * from nw.orders
where substr(to_char(order_date, 'yyyymmdd'), 1,4) = '1997';
to_char(order_date, 'yyyymmdd') 는 Date 형 컬럼인 order_date를 문자열로 변환하는데 yyyymmdd와 같은 형태로 변환하는 것이고, 이렇게 8문자로 변환된 값을 substr(..., 1, 4)로 첫번째 부터 이후 4번째 까지 문자열을 추출한 것이 '1997' 인것만 가져오는 것입니다.
그런데 이렇게 하면 SQL 성능에 영향을 줄 수가 있습니다. 강의에서는 소개하지 않았지만, 빠르게 데이터를 가져오기 위해서 order_date에 index가 달려 있다면 to_char(order_date....) 로 가공하면서 index를 사용하지 못하기 때문에 수행 속도가 느려질 수 있습니다.
감사합니다.
order_date에 index가 달려 있다면 to_char(order_date....) 로 가공하면서 index를 사용하지 못하기 때문에 수행 속도가 느려질 수 있습니다.
라고 답변 주셨는데 혹시 index가 달려있다라는 뜻을 조금만 더 설명해 주실 수 있으실까요??
인덱스는 물리적인 요소로서 테이블의 개별 레코드의 위치를 가지고 있습니다.
일반적으로 where 조건의 컬럼으로 인덱스가 없는 경우 테이블에서 원하는 레코드를 필터링 할때 전체 테이블을 다 읽어들이면서 where조건에 맞는 레코드만 찾아냅니다. 가령 1000만건의 order 테이블이 있고 order_date에 인덱스가 없다면 where order_date = to_date('19970101', 'yyyymmdd') 와 같이 단 하루의 주문 일자에 해당하는 데이터를 찾기 위해서 1000만건을 모두 읽으면서 필터링을 하게 되므로 시간이 많이 소모될 수 있습니다.
이를 개선하기 위해 index를 적용할 수 있습니다. order_date 컬럼에 인덱스를 생성하게 되면 인덱스에 order_date의 값별로 해당 레코드의 위치를 가지고 있습니다. 그래서 1000만건의 order 테이블을 읽기전에 먼저 order_date 인덱스에서 where order_date = to_date('19970101', 'yyyymmdd') 에 해당하는 레코드의 위치를 먼저 찾은 다음에 테이블을 읽기 때문에 대용량 테이블에서 더 빠르게 데이터를 가져 올 수 있습니다.
그런데 where order_date = to_date('19970101', 'yyyymmdd') 가 아니라 where to_char(order_date, 'yyyymmdd') = '19970101' 과 같이 order_date를 to_char() 함수등으로 먼저 가공해버리면 index를 탈수가 없기 때문에 위에서 제가 말씀 드린 쿼리와 같은 형태를 적용할 때는 이런 부분이 있다는 것을 미리 인지하고 있어야 합니다.
늦은시간에 답변 주셔서 감사합니다. 데이터 형식과 변환함수에 대해서 좀 더 공부해보겠습니다.