• 카테고리

    질문 & 답변
  • 세부 분야

    데이터베이스

  • 해결 여부

    미해결

join 실습 관련 질문 있습니다.

22.08.24 18:18 작성 조회수 176

0

안녕하세요! 강의 정말 잘 듣고 있습니다!!!!

본 영상에서 첫번째 예시로 기간 범위에 따른 조회(1997년 주문)를 예시로 들어주셨는데


-- 강사님 예시
SELECT a.contact_name, a.address, b.order_id, b.order_date, b.shipped_date, b.ship_address
FROM customers a
	JOIN orders b ON a.customer_id = b.customer_id
WHERE a.contact_name = 'Antonio Moreno'
AND b.order_date BETWEEN to_date('19970101', 'yyyymmdd')
AND to_date('19971231', 'yyyymmdd');

그런데 기간 범위를 설정할 때 1년 범위 설정 쿼리가 너무 길어보여서 다른 function들을 찾아서 적용해보았습니다.

-- 수정1
SELECT a.contact_name, a.address, b.order_id, b.order_date, b.shipped_date, b.ship_address
FROM customers a
	JOIN orders b ON a.customer_id = b.customer_id
WHERE a.contact_name = 'Antonio Moreno'
AND date_part('year', b.order_date) = '1997';

(물론 이쪽은 연도나 월 등 딱 하나만 인덱싱이 가능하니 한계는 있어보이네요.)

혹은

-- 수정2
SELECT a.contact_name, a.address, b.order_id, b.order_date, b.shipped_date, b.ship_address
FROM customers a
	JOIN orders b ON a.customer_id = b.customer_id
WHERE a.contact_name = 'Antonio Moreno'
AND b.order_date BETWEEN '1997-01-01' AND '1997-12-31';

이렇게 작성해도 결과물은 같긴 하더라고요.

강사님이 들어주신 예시의 to_date()는 검색해보니 대부분 오라클에서 많이 언급되는 것 같은데,

이쪽 쿼리가 더 범용적으로 사용되기에 사용하신 것인지, 아니면 다른 function도 딱히 문제는 없는 것인지 궁금합니다.

강의 최고입니다!! 감사합니다.

답변 1

답변을 작성해보세요.

1

안녕하십니까,

강의가 맘에 드신다니 저도 기분이 좋군요.

수정하신 2개 SQL다 적용이 가능하고 결과도 동일합니다.

문제는 ORDER_DATE에 인덱스가 달려 있을 경우 수정 1의 경우 해당 인덱스를 탈 수가 없어서 수행 속도가 느려 질수가 있습니다. 샘플 데이터라 데이터가 얼마 없어서 그렇지 수정 1과 같이 적용하면 데이터가 많고 ORDER_DATE 검색 시 성능을 높이기 위해서 인덱스를 생성한 경우라면 data_part()함수를 order_date에 적용해 버렸기 때문에 ORDER_DATE 자체의 인덱스를 탈 수가 없습니다.

수정 2의 경우도 DBMS 유형에 따라 인덱스를 타지 못할 수도 있습니다. ORDER_DATE가 Date 타입인데 이걸 문자열로 between 비교해 버리면 DBMS 유형에 따라 to_char(order_date, ...) between .. and ... 로 내부적으로 변경해 버릴 수가 있어서 인덱스를 타지 못할 수 있습니다.

때문에 Date 타입을 where절에 사용할 때는 가급적 date 값으로 비교해 주는게 좋습니다.

감사합니다.

Chromis님의 프로필

Chromis

질문자

2022.08.24

DBMS에 혹시나 달려있을 인덱스를 활용하기 위해서군요!! 생각도 못한 이유였네요.

빠르고 친절한 답변 감사합니다!