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이며, 이것은 최상위 쿼리에 대해서만 실행계획을 볼 수 있다. 이 값은 슈퍼유저만 바꿀 수 있다.

auto_explain.sample_rate (real)

auto_explain.sample_rate causes auto_explain to only explain a fraction of the statements in each session. The default is 1, meaning explain all the queries. In case of nested statements, either all will be explained or none. Only superusers can change this setting.

슈퍼유저는 자신의 세션 안에서 즉시 이 설정을 할 수 있지만, 일반적으로 이 확장 기능을 사용하려면, 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