MySQL ‐ ORDER BY - dnwls16071/Backend_Summary GitHub Wiki
📚 ORDER BY
- 정렬을 처리하는 방법은 인덱스를 이용하는 방법과 쿼리가 실행될 떄, "filesort"라는 별도의 처리를 이용하는 방법으로 나눌 수 있다.
| 장점 | 단점 | |
|---|---|---|
| 인덱스 이용 | INSERT, UPDATE, DELETE 등의 쿼리가 실행될 때, 이미 인덱스가 정렬되어 있어서 순서대로 읽기만 하면 되므로 매우 빠르다. | INSERT, UPDATE, DELETE 등의 작업 시 부가적인 인덱스 추가/삭제 작업이 필요하므로 느리다. 인덱스 때문에 디스크 공간이 더 많이 필요하다. 인덱스 개수가 늘어날수록 InnoDB 버퍼 풀을 위한 메모리가 많이 필요하다. |
| filesort 이용 | 인덱스를 생성하지 않아도 되므로 인덱스를 이용할 때의 단점이 장점으로 바뀐다. 정렬해야 할 레코드가 많지 않다면 메모리에서 filesort가 처리되므로 충분히 빠르다. | 정렬 작업이 쿼리 실행 시 처리되므로 레코드 대상 건수가 많아질수록 쿼리 응답 속도가 느리다. |
소트 버퍼(Sort Buffer)
- MySQL은 정렬을 수행하기 위해 별도의 메모리 공간을 할당받아 사용하는데, 이 메모리 공간을 소트 버퍼라고 한다.
- 소트 버퍼는 정렬이 필요한 경우에만 할당되며, 버퍼 크기는 정렬해야 할 레코드 크기에 따라 가변적으로 증가하지만 최대 사용 가능한 소트 버퍼 공간은
sort_buffer_size라는 시스템 변수로 설정할 수 있다. 소트 버퍼를 위한 메모리 공간은 쿼리 실행이 완료되면 즉시 시스템으로 반납된다. - 메모리 소트 버퍼에서 정렬을 수행하고 그 결과를 디스크에 임시로 기록해 둔다. 그리고 다음 레코드를 가져와서 다시 정렬해서 반복적으로 디스크에 임시 저장한다.
- 이처럼 각 버퍼 크기만큼 정렬된 레코드를 다시 병합하면서 정렬을 수행하는데 이 병합 작업을 멀티 머지(multi-merge)라고 표현하며 수행된 멀티 머지 횟수는 누적해서 집계가 된다.
- 이러한 작업들이 모두 디스크와의 읽기/쓰기를 유발하며, 레코드 건수가 많을수록 이 반복 작업의 횟수가 많아지게 된다.
❗그렇다면 소트 버퍼의 크기를 늘리면 되는 것 아닌가?
- 소트 버퍼를 크게 설정해서 빠른 성능을 얻을 순 없지만, 디스크 읽기/쓰기 사용량은 줄일 수 있다.
- 그래서 MySQL 서버 데이터가 많거나 디스크 I/O 성능이 낮은 장비라면 소트 버퍼 크기를 더 크게 설정하는 것이 도움이 된다.
- 하지만 소트 버퍼를 너무 크게 설정하면 서버의 메모리가 부족해져서 MySQL 서버가 메모리 부족을 겪을 수 있기 때문에 소트 버퍼 크기는 적절히 설정하는 것이 좋다.
- 그리고 대량 데이터의 정렬이 필요한 경우 해당 세션의 소트 버퍼만 일시적으로 늘려서 쿼리를 실행하고 다시 줄이는 것도 좋은 방법이다.
정렬 처리 방법
- 쿼리에 ORDER BY가 사용되면 반드시 다음 3가지 처리 방법 중 하나로 정렬이 처리된다. 일반적으로 아래쪽에 있는 정렬 방법으로 갈수록 처리 속도는 저하된다.
| 정렬 처리 방법 | 실행 계획의 Extra 칼럼 내용 |
|---|---|
| 인덱스를 사용한 정렬 | 별도 표기 없음 |
| 조인에서 드라이빙 테이블만 정렬 | "Using filesort" |
| 조인에서 조인 결과를 임시 테이블로 저장 후 정렬 | "Using temporary; Using filesort" |