【Oracle】SQL Tuning Advisor完全ガイド|DBMS_SQLTUNE・SQL チューニングセット・SQL プロファイル・推奨事項の確認まで解説

「遅い SQL をチューニングしたいが、どこから手をつければよいかわからない」という場面で活躍するのがSQL Tuning Advisor(SQL チューニングアドバイザ)です。Oracle が SQL を自動解析し、統計情報の収集不足・インデックスの欠如・プラン非効率などを検出して推奨事項を提示します。

SQL Tuning Advisor は DBMS_SQLTUNE パッケージから PL/SQL で呼び出せるほか、Oracle Enterprise Manager(OEM)や SQL Developer からも利用できます。

この記事でわかること

  • SQL Tuning Advisor の仕組みと推奨事項の種類
  • DBMS_SQLTUNE.CREATE_TUNING_TASK で sql_id を指定してタスクを作成する
  • EXECUTE_TUNING_TASK・REPORT_TUNING_TASK で解析結果を取得する
  • ACCEPT_SQL_PROFILE で SQL プロファイルを適用する(実行計画を改善する)
  • SQL チューニングセット(STS)で AWR からの複数 SQL を一括解析する
  • タスクの管理(一覧確認・削除)方法
ライセンス要件
SQL Tuning Advisor は Oracle Diagnostics Pack と Oracle Tuning Pack のライセンスが必要です。本番環境で使用する場合は事前にライセンスを確認してください。
スポンサーリンク

SQL Tuning Advisor が提示する推奨事項の種類

推奨種別 内容
Statistics Analysis 統計情報が古い・欠如している場合に再収集を推奨する
SQL Profile より良い実行計画に誘導するためのプロファイルを作成する(ヒント不要)
Access Path Analysis フルスキャンを減らすためのインデックス追加を推奨する
SQL Structure Analysis SQL の書き換えを推奨する(アンチジョインや EXISTS の活用など)
Alternative Plan AWR・SQL Plan Baseline に保存された過去の優良プランを代替案として提示する

sql_id を指定して解析タスクを作成・実行する

カーソルキャッシュから遅い SQL の sql_id を特定する
-- 実行時間が長い SQL の sql_id を特定する
SELECT sql_id, plan_hash_value,
       ROUND(elapsed_time / executions / 1000) AS avg_elapsed_ms,
       executions,
       SUBSTR(sql_text, 1, 80) AS sql_text_head
FROM V$SQLAREA
WHERE executions > 0
  AND elapsed_time / executions > 1000000   -- 平均 1 秒超の SQL
ORDER BY elapsed_time / executions DESC
FETCH FIRST 10 ROWS ONLY;
sql_id を指定してタスクを作成・実行・レポートを取得する
DECLARE
    v_task_name VARCHAR2(30) := 'TUNING_TASK_' || TO_CHAR(SYSDATE, 'YYYYMMDD_HH24MISS');
    v_report    CLOB;
BEGIN
    -- ① チューニングタスクを作成する
    v_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
        sql_id      => 'abc123def456g',   -- V$SQLAREA で確認した sql_id
        plan_hash_value => NULL,            -- NULL = すべてのプランを対象
        scope       => 'COMPREHENSIVE',   -- COMPREHENSIVE(完全解析)/ LIMITED(軽量)
        time_limit  => 60,                  -- 解析の最大実行時間(秒)
        task_name   => v_task_name,
        description => '遅いクエリの解析'
    );
    DBMS_OUTPUT.PUT_LINE('タスク名: ' || v_task_name);

    -- ② タスクを実行する
    DBMS_SQLTUNE.EXECUTE_TUNING_TASK(task_name => v_task_name);

    -- ③ レポートを取得する
    v_report := DBMS_SQLTUNE.REPORT_TUNING_TASK(
        task_name    => v_task_name,
        type         => 'TEXT',   -- TEXT / HTML / XML
        level        => 'TYPICAL' -- TYPICAL / BASIC / ALL(詳細度)
    );
    DBMS_OUTPUT.PUT_LINE(SUBSTR(v_report, 1, 32767));
END;
/

チューニングタスクの一覧確認と管理

タスクの状態と推奨事項を確認する
-- 実行済みタスクの一覧を確認する
SELECT task_name, status, created, last_modified, description
FROM DBA_ADVISOR_TASKS
WHERE advisor_name = 'SQL Tuning Advisor'
ORDER BY created DESC;

-- 推奨事項を確認する(DBA_ADVISOR_FINDINGS / DBA_ADVISOR_RECOMMENDATIONS)
SELECT
    f.task_name,
    f.finding_id,
    f.type,             -- STATISTICS(統計)/ SQL PROFILE / INDEX / RESTRUCTURE SQL など
    f.message,          -- 推奨事項の内容
    r.benefit,          -- 推定改善率(%)
    r.rec_id
FROM DBA_ADVISOR_FINDINGS f
JOIN DBA_ADVISOR_RECOMMENDATIONS r
    ON f.task_id = r.task_id AND f.finding_id = r.finding_id
WHERE f.task_name = 'YOUR_TASK_NAME'
ORDER BY r.benefit DESC;
タスクを削除する
-- 不要になったタスクを削除する
BEGIN
    DBMS_SQLTUNE.DROP_TUNING_TASK(task_name => 'YOUR_TASK_NAME');
END;
/

SQL プロファイルを適用して実行計画を改善する

SQL Tuning Advisor がプロファイルを推奨した場合、ACCEPT_SQL_PROFILE で適用できます。SQL プロファイルはヒント句をソースコードに追加せずに実行計画を誘導できます。

推奨 SQL プロファイルを適用する
-- レポートで推奨された SQL プロファイルを適用する
DECLARE
    v_profile_name VARCHAR2(50);
BEGIN
    v_profile_name := DBMS_SQLTUNE.ACCEPT_SQL_PROFILE(
        task_name    => 'YOUR_TASK_NAME',
        task_owner   => 'SYS',             -- タスクの所有者
        name         => 'PROFILE_SLOW_Q1', -- プロファイル名(省略可)
        force_match  => FALSE,              -- TRUE = バインド変数の値に関係なく適用
        replace      => TRUE               -- TRUE = 同名プロファイルを上書き
    );
    DBMS_OUTPUT.PUT_LINE('適用されたプロファイル名: ' || v_profile_name);
END;
/

-- 適用されたプロファイルを確認する
SELECT name, category, status, sql_text
FROM DBA_SQL_PROFILES
ORDER BY last_modified DESC;

-- プロファイルを無効化する(取り消しではなく一時停止)
BEGIN
    DBMS_SQLTUNE.ALTER_SQL_PROFILE(
        name          => 'PROFILE_SLOW_Q1',
        attribute_name => 'STATUS',
        value          => 'DISABLED'   -- 再有効化は 'ENABLED'
    );
END;
/

-- プロファイルを削除する
BEGIN
    DBMS_SQLTUNE.DROP_SQL_PROFILE(name => 'PROFILE_SLOW_Q1');
END;
/

SQL チューニングセット(STS)で複数 SQL を一括解析する

SQL チューニングセット(STS: SQL Tuning Set)は複数の SQL をまとめて管理・解析するコンテナです。AWR の履歴から問題 SQL を抽出してまとめてチューニングアドバイザにかけるワークフローで使います。

AWR の SQL 履歴から STS を作成して Tuning Advisor にかける
-- ① STS を作成する
BEGIN
    DBMS_SQLTUNE.CREATE_SQLSET(
        sqlset_name => 'STS_SLOW_SQLS',
        description => '過去24時間の遅い SQL 集合'
    );
END;
/

-- ② AWR から STS に SQL を追加する(過去 24 時間・実行時間 1 秒超)
DECLARE
    v_cursor DBMS_SQLTUNE.SQLSET_CURSOR;
BEGIN
    -- AWR の 2 スナップショット間の SQL を取得するカーソルを作成する
    OPEN v_cursor FOR
        SELECT VALUE(p) FROM TABLE(
            DBMS_SQLTUNE.SELECT_WORKLOAD_REPOSITORY(
                begin_snap  => (SELECT MAX(snap_id) - 24 FROM DBA_HIST_SNAPSHOT),  -- 24 スナップ前
                end_snap    => (SELECT MAX(snap_id) FROM DBA_HIST_SNAPSHOT),        -- 最新スナップ
                basic_filter => 'elapsed_time > 1000000',  -- 1 秒超
                ranking_measure1 => 'elapsed_time',
                result_limit => 50                            -- 上位 50 SQL
            )
        ) p;

    -- STS に追加する
    DBMS_SQLTUNE.LOAD_SQLSET(
        sqlset_name     => 'STS_SLOW_SQLS',
        populate_cursor => v_cursor
    );
    CLOSE v_cursor;
END;
/

-- ③ STS 全体にチューニングタスクをかける
DECLARE
    v_task VARCHAR2(50);
BEGIN
    v_task := DBMS_SQLTUNE.CREATE_TUNING_TASK(
        sqlset_name => 'STS_SLOW_SQLS',
        scope       => 'COMPREHENSIVE',
        time_limit  => 300,
        task_name   => 'STS_TUNING_TASK'
    );
    DBMS_SQLTUNE.EXECUTE_TUNING_TASK(task_name => 'STS_TUNING_TASK');
END;
/

-- ④ レポートを出力する
SET LONG 100000
SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK('STS_TUNING_TASK') FROM DUAL;

-- ⑤ STS を削除する(不要になったら)
BEGIN
    DBMS_SQLTUNE.DROP_SQLSET(sqlset_name => 'STS_SLOW_SQLS');
END;
/

まとめ

  • CREATE_TUNING_TASK → EXECUTE_TUNING_TASK → REPORT_TUNING_TASK の3ステップで推奨事項を取得する
  • SQL プロファイルは ACCEPT_SQL_PROFILE で適用。ソースコード変更なしで実行計画を改善できる
  • SCOPE=COMPREHENSIVE は完全解析。制限時間(time_limit)内に収まるよう設定する
  • STS(SQL チューニングセット)で AWR の問題 SQL を一括取得・解析するワークフローが実用的
  • Diagnostics Pack と Tuning Pack のライセンスが必要な点に注意する

AWR スナップショットの取得と分析は AWR・ASH完全ガイドを参照してください。実行計画の詳細確認は DBMS_XPLAN完全ガイドを参照してください。SQL プロファイルとプランの固定化を比較したい場合は SQL Plan Management(SPM)完全ガイドも参照してください。