※本記事は、Ulrike Schwinn による”Diagnose SQL performance with DBMS_SQLDIAG” を翻訳したものです。

2026年5月26日


SQL文に関する関連するオプティマイザ情報を、すべて1か所で確認できたら便利だと思いませんか。SQL文全体のパフォーマンスに影響を与える、有用なオプティマイザ統計、スキーマ・メタデータ、構成パラメータ、その他の要因などです。全体像を把握できれば、それらの問合せが実行されている環境が「良好な状態」にあることを確認するうえで、大いに役立ちます。
23aiでは、DBMS_SQLDIAGパッケージの新しい関数REPORT_SQLにより、このような機能を提供できます。この機能はすべてのデータベース環境で動作します。使い方は非常に簡単で、すべてのOracle Database環境で実行できます。

重要な更新:
Oracle Database RU 19.28により、19cでも利用可能になりました。
機能やRelease Updateに関心がある場合は、ブログ記事New Features and Release Updates in 19c and 23aiで詳細を確認できます。


REPORT_SQLは、My Oracle Supportで提供されているSQL Tuning Health-Check ScriptであるSQLHCの後継です。古いデータベース・バージョンを使用していてSQLHCにアクセスする必要がある場合は、My Oracle Support(Doc ID 1366133.1)からダウンロードできます。
 

使用方法

REPORT_SQLの使い方は非常に簡単です。必要なのは文のSQL_IDだけで、その後REPORT_SQL関数を実行します。指定したSQL文に関する一連のヘルスチェック結果を含むHTMLレポートが生成されます。オンプレミスまたはクラウド上の、すべてのOracle Databaseエディションで使用できます。

この記事では、Autonomous Databaseやその他のデータベース環境など、さまざまな環境でREPORT_SQLを使用する方法を示します。

構文は、DBMS_SQLDIAGPL/SQL Packages and Types Referenceに記載されています。

DBMS_SQLDIAG.REPORT_SQL(sql_id IN VARCHAR2, directory IN VARCHAR2, level IN VARCHAR2 ) RETURN CLOB
  • LEVELには3つのオプションがあります。最小限のレポート詳細を出力するBASIC、より高度なレポート・セクションを含む標準(デフォルト)のレポートであるTYPICAL、および利用可能なすべてのレポート情報を含む完全なレポートであるALLです。
  • デフォルトでは、レポートはCLOBとして返され、ディスクには書き込まれません。DIRECTORY引数にディレクトリ名を指定すると、ファイル名はSQLR_<SQL_ID>_<YYYYMMDDHH24MI>.htmlという形式で作成されます。

文のSQL_IDを確認するには、AWR、ASH、V$SQL、または利用可能であればSQL*Plusの設定set feedback on sql_idを使用します。
最初のテストの例を次に示します。

SQL> set feedback on sql_id
SQL> SELECT p.prod_id, SUM(quantity_sold) AS sold
     FROM   products p, sales s
     WHERE  p.prod_id = s.prod_id and lower(prod_category) like '%tennis' and prod_code = 1 
     GROUP BY p.prod_id
     union
     SELECT s.prod_id, SUM(s.amount_sold) AS sold
     FROM   sales s, sales p where s.time_id>=sysdate
     GROUP BY s.prod_id;

PROD_ID       SOLD
---------- ----------
       140      14769
       146      12742
   ....
SQL_ID: 6wckp3ksb32m9

REPORT_SQLの使用方法を示し、内容をreportという名前のCLOB変数に返してみましょう。

set feedback on
var report clob;
exec :report := dbms_sqldiag.report_sql('6wckp3ksb32m9'); 
PL/SQL procedure successfully completed.

次に、以下のフォーマット設定を使用してファイルをスプールします。

set trimspool on 
set trim on
set pagesize 0
set linesize 32767
set long 1000000
set longchunksize 1000000

spool diagsql1.html
select :report report from dual;
spool off

結果として、実行計画、計画履歴、デフォルト以外のデータベース・パラメータ、統計履歴、索引などを含むHTMLレポートが生成されます。
以下はHTMLレポートのヘッダー情報です。

DIAG Report

2つ目の例では、Autonomous Database Serverless(ADB-S)と、HTMLファイルを保存するためのディレクトリDATA_PUMP_DIRを使用します。

まず、利用可能なすべてのディレクトリを一覧表示します。

SQL> select directory_name 
     from all_directories;
DIRECTORY_NAME 
-------------- 
SQL_TCB_DIR    
DATA_PUMP_DIR 

SQL_IDfbr2p8gp9d5dnである次の文を使用してみましょう。

SELECT p.prod_id, sum(quantity_sold) AS sold
FROM sh.products p, sh.sales s
WHERE p.prod_id = s.prod_id and lower(prod_category) =’photo’
GROUP BY p.prod_id
union
SELECT s.prod_id, sum(s.amount_sold) AS sold
FROM sh.sales s, sh.sales p where s.time_id>=sysdate
GROUP BY s.prod_id;

このケースでは、ディレクトリDATA_PUMP_DIR内にHTMLレポートを生成します。

declare
my_report clob;
begin
 my_report := dbms_sqldiag.report_sql('fbr2p8gp9d5dn', directory=>'DATA_PUMP_DIR', level=>'ALL');
end;
/

少しすると、「PL/SQL procedure successfully completed」というメッセージが表示されます。
ここで、HTMLファイルを取得するためにパッケージDBMS_CLOUDを使用します。


出力ファイルは、DBMS_CLOUD.LIST_FILESを使用して一覧表示できます。

SQL> select * 
     from table(dbms_cloud.list_files('DATA_PUMP_DIR'));
OBJECT_NAME                                BYTES CHECKSUM   CREATED                             LAST_MODIFIED                      
------------------------------------- ---------- ---------- ----------------------------------- -----------------------------------
SQLR_fbr2p8gp9d5dn_202411201540.html      278497            20-NOV-24 03.40.41.533979000 PM GMT 20-NOV-24 03.41.04.139479000 PM GMT

次のステップでは、BLOBファイルのコピーをAutonomous DatabaseからCloud Object Storeに転送します。そのために、DBMS_CLOUD.PUT_OBJECTを使用できます。
資格証明情報を確認してみましょう。

SQL> select * from dba_credentials;
OWNER CREDENTIAL_NAME 
----- --------------- 
ADMIN CREDENTIAL_US1   

ここで、次のようにDBMS_CLOUD.PUT_OBJECTを使用します。

BEGIN
 DBMS_CLOUD.PUT_OBJECT(credential_name =>'CREDENTIAL_US1', 
                        object_uri     => 'https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/tenant_name
                                           /b/bucket_name/o/SQLR_fbr2p8gp9d5dn_202411201540.html', 
                       directory_name  => 'DATA_PUMP_DIR',
                       file_name       => 'SQLR_5yaurap8h97nx_202411181751.html');
END;

これでファイルはCloud Object Storeに配置されます。環境にダウンロードすることで、このSQL文に対して生成された詳細レベルのHTML診断レポート情報を取得できます。

まとめ

新しい関数REPORT_SQLはOracle Databaseに組み込まれており、特定のSQL文に関連する情報を詳細レベルで診断表示できるようにすることを目的としています。SQLHCによって提供されていた機能を置き換え、さらに拡張することを意図しています。使い方は非常に簡単で、すべてのOracle Database環境で実行できます。
 

参考資料