Posts MySQL - MySQL 실행 계획 (1)
Post
Cancel

MySQL - MySQL 실행 계획 (1)

들어가기 전


슬로우 쿼리를 고쳐보고 싶은데 어떤 부분에서 비효율이 발생하는지는 “실행 계획”을 보면 알 수 있다고 들었다. 실행 계획이 무엇이고 어떻게 활용해야 하는 것인지 공부해보자.

실행 계획


DBMS의 쿼리 실행은 같은 결과를 만들어 내는 다양한 방법이 있다. 그 중 어떤 방법이 최적이고 최소의 비용이 소모될지 결정해야 한다. 이러한 최적의 실행 계획을 수립하는 역할은 옵티마이저가 담당한다.

  • 실행 계획을 이해할 수 있어야 불합리한 부분을 찾아내고, 최적화된 방법으로 실행 계획을 수립하도록 유도할 수 있다.
  • MySQL 서버에서 쿼리가 실행되는 과정은 크게 다음과 같이 구분할 수 있다.
  1. 파싱(SQL 파서)
    • 쿼리 문장을 MySQL 서버가 이해할 수 있는 수준으로 분리(파스 트리 생성)
  2. 최적화 및 실행 계획 수립(옵티마이저)
    • 파스 트리를 기반으로 어떤 테이블부터 읽고 어떤 인덱스를 이용해서 테이블을 읽을지 선택
    • 2번 단계가 완료되면 실행 계획이 만들어진다.
  3. 수립된 실행 계획대로 스토리지 엔진에 레코드를 읽어오도록 요청. MySQL 엔진에서는 스토리지 엔진으로부터 받은 레코드를 조인하거나 정렬하는 작업 수행

옵티마이저의 최적화 방법

현재 많은 DBMS가 선택하고 있는 비용 기반 최적화(Cost-based optimizer, CBO) 방법과 예전 오라클에서 많이 사용했던 규칙 기반 최적화(Rule-based optimizer, RBO)로 나눌 수 있다.

  • 규칙 기반 최적화
    • 오직 옵티마이저에 내장된 우선순위에 따라 실행 계획을 수립하는 방식이다.
    • 이 방식에서는 통계 정보(대상 테이블의 레코드 건수, 컬럼 값의 분포도 등)를 고려하지 않고 실행 계획이 수립된다.
    • 각 테이블이나 인덱스의 통계 정보가 거의 없고, 상대적으로 느린 CPU 연산 탓에 비용 계산 과정이 부담스러웠기 때문에 사용하던 방식이다.
      • 이미 오래 전부터 많은 DBMS에서 더 이상 지원하지 않는다.
  • 비용 기반 최적화
    • 산출된 각 실행 계획별 최소 비용이 소요되는 처리 방식을 선택한다.
    • 쿼리를 처리하기 위한 여러 방법을 수립한다.
    • 각 단위 작업의 비용(부하) 정보와 대상 테이블의 예측된 통계 정보를 이용해 각 실행 계획별 비용을 산출한다.

통계 정보

비용 기반 최적화 방식에서 가장 중요한 것은 ‘통계 정보’이다. 통계 정보가 정확하지 않으면 쿼리가 매우 비효율적으로 실행될 수 있다.

  • 기본적으로 MySQL에서 관리되는 통계 정보는 대략의 레코드 건수인덱스의 유니크한 값의 개수정도이다.
    • 레코드 건수가 많지 않으면 정보가 부정확한 경우가 많으므로 ANALYZE 명령을 이용해 강제적으로 통계 정보를 갱신해야 할 때도 있다.
  • 오라클과 같은 DBMS에서는 통계 정보가 상당히 정적이고 수집에 많은 시간이 소요되기 때문에 통계 정보만 따로 백업하기도 한다.

실행 계획 분석


MySQL에서는 기본적으로 EXPLAIN 명령을 사용해서 실행 계획을 확인할 수 있다. 또한, EXPLAIN EXTENDED, EXPLAIN PARTITIONS 명령을 이용해 더 상세한 실행 계획을 확인할 수도 있다.

  • EXPLAIN을 실행하면 다음과 같이 표 형태로된 결과가 표시된다. image
  • 표의 각 라인은 쿼리 문장에서 사용된 테이블(서브 쿼리를 통해 생성된 임시 테이블도 포함)의 개수만큼 출력된다.
  • 표의 위쪽에 있을수록 먼저 접근한 테이블이다.
  • 다른 DBMS와는 달리 MySQL에서는 필요에 따라 실행 계획을 산출하기 위해 쿼리의 일부분을 직접 실행할 때도 있다.
    • 따라서 쿼리 자체가 상당히 복잡하고 무거운 경우에는 실행 계획의 조회 또한 느려질 가능성이 있다.
  • SELECT 이외의 DML(UPDATE, INSERT, DELETE)에 대해서는 실행계획을 확인할 방법이 없다.
    • 이를 위해서는 WHERE 조건절만 같은 SELECT 쿼리를 만들어서 대략적으로 계획을 확인해 볼 수 있다.


다음 파트에서부터 실행 계획의 각 컬럼이 어떤 것을 의미하는지, 어떤 값이 나올 수 있는지 등에 대해 살펴볼 것이다.

관련 글


참고 자료


  • 이성욱, 『개발자와 DBA를 위한 Real MySQL』, 위키북스(2012), 6장
This post is licensed under CC BY 4.0 by the author.

MySQL - MySQL 내부 구조 간단히 살펴보기

MySQL - MySQL 실행 계획 (2)