본문 바로가기

개발하자/DB&SQL

인덱스 스캔과 테이블 풀스캔

* union을 사용

SELECT key, name,
       date_1, flg_1,
       date_2, flg_2,
       date_3, flg_3
 FROM ThreeElements
 WHERE date_1 = '2013-11-01'
   AND flg_1 = 'T'
UNION
SELECT key, name,
       date_1, flg_1,
       date_2, flg_2,
       date_3, flg_3
 FROM ThreeElements
 WHERE date_2 = '2013-11-01'
   AND flg_2 = 'T'
UNION
SELECT key, name,
       date_1, flg_1,
       date_2, flg_2,
       date_3, flg_3
 FROM ThreeElements
 WHERE date_3 = '2013-11-01'
  AND flg_3 = 'T';

 

*where절에 or를 사용

SELECT key, name,
       date_1, flg_1,
       date_2, flg_2,
       date_3, flg_3
 FROM ThreeElements
 WHERE (date_1 = '2013-11-01' AND flg_1 = 'T')
    OR (date_2 = '2013-11-01' AND flg_2 = 'T')
    OR (date_3 = '2013-11-01' AND flg_3 = 'T');

 

where절에 or를 사용하면 해당 필드에 부여된 인덱스를 사용할 수 없어서 테이블 풀 스캔을 진행하게 된다. or대신 in이나 case를 사용해도 마찬가지이다.

union을 사용할 때 테이블의 레코드 수가 적은경우에는 옵티마이저가 인덱스 스캔을 선택하지 않고 테이블 풀 스캔을 선택할 가능성이 크지만 테이블의 크기가 커지고 인덱스로 레코드 압축이 잘 된다면 인덱스 스캔이 훨씬 좋은 성능을 낸다.

 

 

3회의 인덱스 스캔 vs 1회의 테이블 풀 스캔 이라는 문제이다.

 

union이 조건분기를 위해 만들어진 것이 아니므로

예외적인 몇 가지 상황을 제외하면 union을 사용하지 않는 것이 성능적으로도 좋고 가독성도 좋다.

반대로 case식은 조건 분기를 위해 만들어졌으므로 case식을 사용하는 것이 훨씬 자연스럽다.

'개발하자 > DB&SQL' 카테고리의 다른 글

윈도우 함수 RANK() , DENSE_RANK()  (0) 2018.07.03
윈도우 함수로 카운트하기  (0) 2018.07.03
mysql ALIAS_FOR_SUBQUERY  (0) 2018.06.01