2010년 12월 25일 토요일

GROUP BY의 Filesort 작업 제거

다른 DBMS와는 달리,
MySQL은 GROUP BY 를 실행하면 GROUP BY 대상 컬럼을 기준으로 
GROUP BY를 실행한 후, 정렬 작업까지 같이 수행하도록 구현되어 있다.

이러한 자동 정렬 기능이 때로는 필요할 수도 있고, 필요치 않은 경우도 많이 있지만 
특별히 이를 제어할 수 있는 방법이 공유되지 않았기 때문에 정렬 작업이 필요치 않은 경우에도 
불필요한 정렬 작업을 같이 실행시키고 있는 경우가 많았다.

간단히 GROUP BY 작업에 대한 실행 계획을 확인해보자.
root@localhost:test>explain select * from user group by name ;      
+----+-------------+-------+------+..------+..------+---------------------------------+
| id | select_type | table | type |.. key  |.. rows | Extra                           |
+----+-------------+-------+------+..------+..------+---------------------------------+
|  1 | SIMPLE      | user  | ALL  |.. NULL |.. 5288 | Using temporary; Using filesort |
+----+-------------+-------+------+..------+..------+---------------------------------+
user 테이블의 name 컬럼에는 인덱스가 없으므로 GROUP BY 시에 Temporary 테이블을 생성하는 것은 피할 수 없다.
하지만, Filesort 작업은 ... 어떻게 하면 이 정렬 작업을 빼고 Grouping 작업만 할 수 있을까?

해결 방법은 GROUP BY 절 뒤에 ORDER BY NULL을 붙혀주면 된다.
아래 쿼리 문장의 실행 계획을 확인해보자
root@localhost:test>explain select * from user group by name order by null;
+----+-------------+-------+------+..------+..------+-----------------+
| id | select_type | table | type |.. key  |.. rows | Extra           |
+----+-------------+-------+------+..------+..------+-----------------+
|  1 | SIMPLE      | user  | ALL  |.. NULL |.. 5288 | Using temporary |
+----+-------------+-------+------+..------+..------+-----------------+

실행 계획의 Extra 컬럼에서 Filesort 조작이 실행되지 않았음을 알 수 있다.

이는 SQL 표준이라기 보다는 MySQL에서만 특이하게 작동되는 방식으로,
MySQL 개발사에 사용자들의 의견을 수렵하여 추가로 구현한 회피책 같은 것으로 생각하면 될 것 같다.

실제로 정렬 작업까지 수행하는 GROUP BY 와 정렬을 수행하지 않고 GROUPING만 하는 작업은
업무 성격에 따라서 매우 큰 성능 차이를 보이는 경우도 많다.
업무적으로 GROUPING만 필요한 것인지, 정렬도 필요한 것인지를 명확히 따져서
필요한 작업만 수행하도록 하는 것이 최선으로 보인다.

댓글 없음:

댓글 쓰기