F.3. auto_explain

auto_explain 모듈은 서버에서 실행된 쿼리들 가운데, 그 수행 시간이 일정시간 이상 된 것들에 대해서, EXPLAIN 결과를 자동으로 로그에 남기는 기능을 제공한다. 이 모듈은 규모가 큰 응용 프로그램에 사용되는 최적화 되지 못한 쿼리들들 찾아 문제를 해결하는데, 특히 도움이 될 것이다.

이 모듈은 SQL 명령어에서 사용할 함수를 제공하지 않는다. 그냥 서버에 해당 모듈만 로딩하고, 환경 설정만 하면 된다: 특정 세션에서 바로 사용하려면 다음과 같이 LOAD 명령을 이용한다:

LOAD 'auto_explain';

(이 작업은 슈퍼유저 권한이어야 가능하다.) 일반적으로는 postgresql.conf 파일의 session_preload_libraries 설정 값이나 shared_preload_libraries 설정 값으로 auto_explain 문자열을 추가 해서, 서버가 실행 될 때나, 세션이 만들어질 때 미리 로딩을 하고, 이 모듈을 모든 세션이나 접속한 세션에서 사용할 수 있도록 한다. 이렇게 해서 언제 실행 될지 모르는 최적화 되지 못한 쿼리를 찾는 일과 그 쿼리를 최적화 하기 위한 정보들을 쉽게 수집할 수 있다. 물론 이 작업은 그 만큼의 서버 부하를 더 일으킬 것임을 감안 해야 할 것이다.

F.3.1. 환경설정 매개변수들

auto_explain 모듈의 동작 방식을 제어하는 여러 환경 설정 값들이 있다. 초기값은 어떠한 작업도 하지 않는 것이다. 즉, 이 모듈이 정상적으로 작동 하려면, 적어도 auto_explain.log_min_duration 설정값 정도는 조정해 주어야 이 모듈의 동작 상태를 확인 할 수 있다.

auto_explain.log_min_duration (integer)

auto_explain.log_min_duration 설정은 쿼리 실행 시간이 해당 밀리초 이상인 경우에 실행 계획을 확인하도록 한다. 0으로 지정하면 모든 쿼리를 대상으로 한다. -1(초기값)이면 이 모듈의 기능을 사용하지 않는다. 예를 들어, 이 값으로 250ms 로 지정했다면, 쿼리 실행 시간이 0.25초 이상 걸린 쿼리들에 대해서 자동으로 실행계획을 살펴 볼 수 있도록 한다. 이 값은 슈퍼유저만 바꿀 수 있다.

auto_explain.log_analyze (boolean)

auto_explain.log_analyze 설정은 실행계획 작업을 EXPLAIN ANALYZE 명령으로 진행할 것인지를 지정한다. (ANAYZE 옵션은 쿼리를 실제로 실행해서 각 실행 단계에서의 참조값들을 실제값들로 보여준다. - 옮긴이) 초기값은 off 다. 이 값은 슈퍼유저만 바꿀 수 있다.

참고: 이 값을 on으로 바꾸면, 위에서 설명한 것처럼 그 작업 부하가 많이 발생한다. 운영 환경에서는 이 값을 on으로 바꾸면 많이 위험하다. 주의 해야 한다.

auto_explain.log_verbose (boolean)

auto_explain.log_verbose 설정은 실행계획 작업을 EXPLAIN VERBOSE 명령으로 진행 할 것인지를 지정한다. 초기값은 off 다. 이 값은 슈퍼유저만 바꿀 수 있다.

auto_explain.log_buffers (boolean)

auto_explain.log_buffers 설정은 실행계획 작업을 EXPLAIN (ANALYZE, BUFFERS) 명령으로 진행 할 것인지를 지정한다. 초기값은 off 다. 이 값은 슈퍼유저만 바꿀 수 있다. 이 설정은 사용하려면, auto_explain.log_analyze 값이 on 이어야 한다.

auto_explain.log_format (enum)

auto_explain.log_format 설정은 EXPLAIN 명령의 출력 양식을 지정한다. 사용할 수 있는 출력 양식은 text, xml, json, yaml 이다. 초기값은 text 이다. 이 값은 슈퍼유저만 바꿀 수 있다.

auto_explain.log_timing (boolean)

auto_explain.log_timing 설정은 실행계획을 기록할 때 각 노드별 수행 시간도 함께 기록할 것인지를 결정할 수 있다. 여기서 사용하는 값은 EXPLAIN 명령의 TIMING 옵션값과 동일하다. 각 실행 단계별 시간을 계산하지 않음으로 몇몇 시스템에서는 실행 계획 작업에 소비하는 비용을 어느 정도는 줄일 수 있어 유용하게 사용할 수 있다. 이 설정은 사용하려면, auto_explain.log_analyze 값이 on 이어야 한다. 이 설정의 초기값은 on이다. 이 설정은 슈퍼유저만 바꿀 수 있다.

auto_explain.log_nested_statements (boolean)

auto_explain.log_nested_statements 설정은 실행되는 쿼리에서 사용된 숨어 있는 쿼리들 (함수 안에서 실행 되는 쿼리들)에 대한 것도 함께 실행계획을 살펴 볼 수 있다. 초기값은 off이며, 이것은 최상위 쿼리에 대해서만 실행계획을 볼 수 있다. 이 값은 슈퍼유저만 바꿀 수 있다.

슈퍼유저는 자신의 세션 안에서 즉시 이 설정을 할 수 있지만, 일반적으로 이 확장 기능을 사용하려면, postgresql.conf 파일에 적어도 아래 두 가지 설정은 있어야 한다:

# postgresql.conf
session_preload_libraries = 'auto_explain'

auto_explain.log_min_duration = '3s'

F.3.2. 예제

postgres=# LOAD 'auto_explain';
postgres=# SET auto_explain.log_min_duration = 0;
postgres=# SELECT count(*)
           FROM pg_class, pg_index
           WHERE oid = indrelid AND indisunique;

This might produce log output such as:

LOG:  duration: 3.651 ms  plan:
  Query Text: SELECT count(*)
              FROM pg_class, pg_index
              WHERE oid = indrelid AND indisunique;
  Aggregate  (cost=16.79..16.80 rows=1 width=0) (actual time=3.626..3.627 rows=1 loops=1)
    ->  Hash Join  (cost=4.17..16.55 rows=92 width=0) (actual time=3.349..3.594 rows=92 loops=1)
          Hash Cond: (pg_class.oid = pg_index.indrelid)
          ->  Seq Scan on pg_class  (cost=0.00..9.55 rows=255 width=4) (actual time=0.016..0.140 rows=255 loops=1)
          ->  Hash  (cost=3.02..3.02 rows=92 width=4) (actual time=3.238..3.238 rows=92 loops=1)
                Buckets: 1024  Batches: 1  Memory Usage: 4kB
                ->  Seq Scan on pg_index  (cost=0.00..3.02 rows=92 width=4) (actual time=0.008..3.187 rows=92 loops=1)
                      Filter: indisunique

F.3.3. 만든이

Takahiro Itagaki