SQL パフォーマンス分析ツールキット
InterSystems IRIS は、特定の SQL 文の積極的なプロファイリングに使用できる分析ツールを用意しています。このツールは、そのような SQL 文の実行に関する詳細な情報を収集するので、クエリ・プランの中で特定の問題を特定するうえで効果的です。収集した情報を使用して、開発者は非効率な SQL 文のパフォーマンスを改善するための対策を講じることができます。ただし、積極的なプロファイリングによって、サーバに対する負荷が著しく増加することがあります。したがって、SQL パフォーマンス分析ツールキットでは、SQL 実行時統計情報の調査を経て詳しい検討を必要とするクエリを特定した後で、協調性のあるコード分析を進めることを目的としています。実行コードを継続的に監視するためのものではありません。
%SYSTEM.SQL.PToolsOpens in a new tab クラス・メソッドは、この機能を呼び出すための推奨 API です。%SYSTEM.SQL.PToolsOpens in a new tab メソッド・インタフェースは、%SYS.PTools ベース・クラスのメソッドに実装された機能を再グループ化および再編成します。
SQL パフォーマンス統計の有効化
サポート・スペシャリストは、SQL パフォーマンス分析ツールキットを使用して、特定の SQL 文または SQL 文のグループをプロファイリングできます。特定の SQL 文の実行時にこれらのツールを使用してパフォーマンス統計を収集し、その情報を使用して問題のある文を切り分けて分析したり、実際の作業負荷で分析したりすることができます。
%SYSTEM.SQL.PToolsOpens in a new tab クラスのメソッドを使用すると、高度なパフォーマンス統計の収集を開始できます。このような統計をさまざまな規模で収集するために以下のメソッドが用意されています。
-
システム全体 : setSQLStatsFlag()Opens in a new tab
-
特定のネームスペース : setSQLStatsFlagByNS()Opens in a new tab
-
現在のプロセスまたはジョブ : setSQLStatsFlagJob()Opens in a new tab
-
指定したプロセスまたはジョブ : setSQLStatsFlagByPID()Opens in a new tab。最初のパラメータが未指定の場合、あるいは $JOB または空の文字列 ("") として指定されている場合、setSQLStatsFlagJob() が呼び出されます。したがって、SET SQLStatsFlag=$SYSTEM.SQL.SetSQLStatsFlagByPID($JOB,3) は SET SQLStatsFlag=$SYSTEM.SQL.SetSQLStatsFlagJob(3) と同等です。
これらのメソッドは、整数のアクション・オプションを取ります。返される情報は、コロンで区切られた文字列です。その最初の要素は、優先するアクション・オプションです。現在の設定を確認するには、getSQLStatsFlag() メソッドまたは getSQLStatsFlagByPID() メソッドを使用します。
これらのメソッドは、以下の例に示すように、ObjectScript から呼び出すことも、SQL から呼び出すこともできます。
-
ObjectScript から : SET rtn=##class(%SYSTEM.SQL.PTools).setSQLStatsFlag(2,,8)
-
SQL から : SELECT %SYSTEM_SQL.PTools_setSQLStatsFlag(2,,8)
また、SELECT 文、INSERT 文、UPDATE 文、または DELETE 文で %PROFILE キーワード (setSQLStatsFlagJob(2) と同じ) または %PROFILE_ALL キーワード (setSQLStatsFlagJob(3) と同じ) を使用すると、その文のみのパフォーマンス分析統計を収集できます。
アクション・オプション
setSQLStatsFlag() と setSQLStatsFlagByNS() については、以下のいずれかのアクション・オプションを指定します。0 に設定すると、統計コードの生成が無効になります。1 に設定すると、すべてのクエリに対して統計コードの生成が有効になりますが、統計は収集されません (既定値)。2 に設定すると、クエリの外側のループのみの統計が記録されます (クエリのオープンおよびクローズ時に統計が収集されます)。3 に設定すると、クエリのすべてのモジュール・レベルに対して統計が記録されます。モジュールは入れ子にすることができます。その場合、MAIN モジュールの統計が包含的な数となり、全クエリに対する全体的な結果となります。
setSQLStatsFlagJob() と setSQLStatsFlagByPID() については、アクション・オプションが多少異なります。-1 を指定すると、このジョブの統計が無効になります。0 を指定すると、システム設定値が使用されます。1、2、および 3 のオプションは setSQLStatsFlag() と同様であり、システム設定がオーバーライドされます。既定値は 0 です。
SQL パフォーマンス統計を収集するには、統計コードの生成を有効にして (オプション 1、既定値) クエリをコンパイル (準備) する必要があります。
-
0 から 1 に変更する場合:アクション・オプションの変更後、SQL を含んでいるルーチンとクラスは統計コードの生成を実行するためにコンパイルする必要があります。ダイナミック SQL またはデータベース・ドライバを使用する場合は、コードの生成を強制するために、クエリ・キャッシュを削除する必要があります。
-
1 から 2 に変更する場合:アクション・オプションを変更するだけで、統計の収集が開始されます。これにより、最短の中断で稼働中のプロダクション環境に関する SQL パフォーマンスの分析を実行できるようになります。
-
1 から 3 (または 2 から 3) に変更する場合:アクション・オプションの変更後、SQL を含んでいるルーチンとクラスは、すべてのモジュール・レベルの統計を記録するためにコンパイルする必要があります。ダイナミック SQL またはデータベース・ドライバを使用する場合は、コードの生成を強制するために、クエリ・キャッシュを削除する必要があります。一般に、オプション 3 は、非プロダクション環境で特定したパフォーマンスの低いクエリにのみ使用します。
-
1,2,または 3 から 0 に変更する場合:統計コードの生成をオフにするために、クエリ・キャッシュを削除する必要はありません。
収集オプション
アクション・オプションが 2 または 3 である場合、これらのいずれかのメソッドを呼び出す際に、収集オプション値を指定して、収集するパフォーマンス統計を指定することができます。既定では、すべての統計が収集されます。
収集オプションを指定するには、収集するそれぞれの統計タイプに関連付けられた整数値を合計します。既定値は 15 (1 + 2 + 4 + 8) です。
これらのメソッドは、コロンで区切られた 2 つ目の要素としてこの収集オプションの以前の値を返します。現在の設定を確認するには、getSQLStatsFlag() メソッドまたは getSQLStatsFlagByPID() メソッドを使用します。既定では、すべての統計が収集され、2 つ目の要素の値として 15 が返されます。
詳細は、"%SYSTEM.SQL.PTools" を参照してください。
終了オプション
統計の収集は、終了するまで続行されます。既定では、別の setSQLStatsFlag[nnn]() メソッドを発行して終了するまで、収集が無期限に続行されます。また、アクション・オプションが 1、2、または 3 である場合は、setSQLStatsFlag[nnn]() 終了オプション (経過期間 (分単位) またはタイムスタンプ) を指定することもできます。続いて、その期間が経過したときにリセットするアクション・オプションを指定します。例えば、"M:120:1" という文字列では、M (経過分数) が 120 分に設定され、その期間の終了時にアクション・オプションが 1 にリセットされます。他のオプションはすべて、そのアクション・オプションに応じた既定値にリセットされます。
これらのメソッドは、コロンで区切られた 5 つ目の要素としてこの終了オプションの以前の値をエンコードされた値で返します。"統計設定の取得" を参照してください。
管理ポータルでのパフォーマンス統計の有効化
以下のいずれかのパスを使用して、[SQL 実行時統計情報] ページの [設定] タブで管理ポータルのパフォーマンス統計を収集するためのアクション・オプションを設定できます。
-
[システムエクスプローラ]→[ツール]→[SQL パフォーマンス・ツール]→[SQL 実行時統計情報]
-
[システムエクスプローラ]→[SQL]→[ツール]→[SQL 実行時統計情報]
統計設定の取得
setSQLStatsFlag[nnn]() メソッドは、以前の統計設定をコロンで区切られた値として返します。現在の設定を確認するには、getSQLStatsFlag()Opens in a new tab メソッドまたは getSQLStatsFlagByPID()Opens in a new tab メソッドを使用します。
コロンで区切られた 1 つ目の値は、アクション・オプションの設定です。コロンで区切られた 2 つ目の値は、収集オプションです。コロンで区切られた 3 つ目の値と 4 つ目の値は、ネームスペース固有の統計の収集に使用されます。コロンで区切られた 5 つ目の値は、終了オプションをエンコードしたものです。コロンで区切られた 6 つ目の値では FlagType を指定します。0 = システム・フラグ、1 = プロセス/ジョブ・フラグです。
以下の例に示すように、ptInfo 配列を使用して、終了オプションの設定をより詳細に表示できます。
KILL
DO ##class(%SYSTEM.SQL.PTools).clearSQLStatsALL("USER")
DO ##class(%SYSTEM.SQL.PTools).setSQLStatsFlagByNS("USER",3,,7,"M:5:1")
DisplaySettings
SET SQLStatsFlag = ##class(%SYSTEM.SQL.PTools).getSQLStatsFlag(0,.ptInfo)
WRITE "ptInfo array of performance statistics return value:",!
ZWRITE ptInfo,SQLStatsFlag
クエリ・パフォーマンス統計のエクスポート
%SYSTEM.SQL.PToolsOpens in a new tab の exportSQLStats()Opens in a new tab メソッドを使用して、クエリ・パフォーマンス統計をファイルにエクスポートできます。このメソッドは、%SYSTEM.SQL.PToolsOpens in a new tab クラスから統計データをファイルにエクスポートする場合に使用します。
exportSQLStats() は、以下の例に示すように呼び出すことができます。
-
ObjectScript から : SET status=##class(%SYSTEM.SQL.PTools).exportSQLStats("$IO") (既定値は format T です)。
-
SQL から : CALL %SYSTEM_SQL.PTools_exportSQLStats('$IO') (既定値は format H です)。
filename 引数を指定しなかった場合、このメソッドは現在のディレクトリにエクスポートします。既定では、このファイルの名前は、PT_StatsSQL_exportSQLStats_ の後に現在のローカル日時が YYYYMMDD_HHMMSS として付加されたものになります。$IO を指定すると、データをターミナルまたは管理ポータルのディスプレイに出力できます。filename 引数を指定した場合、このメソッドは、現在のネームスペースの Mgr サブディレクトリ、または指定したパスの場所にファイルを作成します。このエクスポートは、現在のネームスペース内のデータに限られます。
出力ファイルの format を P (テキスト)、D (コンマ区切りのデータ)、X (XML マークアップ)、H (HTML マークアップ)、または Z (ユーザ定義の区切り文字) として指定できます。
既定では、このメソッドはクエリ・パフォーマンス統計をエクスポートします。以下の例に示すように、代わりに SQL クエリ・テキストまたは SQL クエリ・プラン・データをエクスポートするように指定することもできます。
-
クエリ・テキスト : CALL %SYSTEM_SQL.PTools_exportSQLStats('$IO',,0,1,0)
-
クエリ・プラン : CALL %SYSTEM_SQL.PTools_exportSQLStats('$IO',,0,1,1)
exportSQLStats() は、コメントを削除し、リテラル置換を実行することにより、クエリ・テキストを変更します。
ExportSQLQuery()Opens in a new tab によって、同じクエリ・テキストおよびクエリ・プラン・データを返すことができます。
統計値
以下の統計が返されます。
-
RowCount - 指定されたクエリの MAIN モジュールで返された行の合計数。
-
RunCount - クエリが最後にコンパイルまたは準備された後で実行された合計回数。
-
ModuleCount - クエリの実行中に、指定されたモジュールに入った合計回数。
-
TimeToFirstRow - 指定されたクエリの MAIN モジュールに最初の結果セット行を返すまでに要した合計時間。
-
TimeSpent - 指定されたクエリの指定されたモジュールで費やされた合計時間。
-
GlobalRefs - 指定されたクエリの指定されたモジュールで行われたグローバル参照の合計数。
-
LinesOfCode - 指定されたクエリの指定されたモジュールで実行された ObjectScript コードの合計行数。
-
DiskWait (ディスク待ち時間とも呼ばれる) - 指定されたクエリの指定されたモジュールでディスク読み取りの待機に要した合計時間 (ミリ秒単位)。
SQL 統計では、実行されているクエリのすべてのコンポーネントについての集約カウンタ値を報告します。このようなコンポーネントには、並列クエリのすべてのパーティションや、シャード・クエリのすべてのシャードが含まれます。
クエリ・パフォーマンス統計の削除
clearSQLStatsALL()Opens in a new tab メソッドを使用すると、パフォーマンス統計を削除できます。既定では、現在のネームスペースのすべてのルーチンに対して収集された統計が削除されます。異なるネームスペースの指定、特定のルーチンへの削除操作の限定、またはその両方を指定できます。
また、管理ポータルの [SQL 実行時統計情報] ページで [統計情報を削除] ボタンを使用して、現在のネームスペースのすべてのクエリについて蓄積されたすべての統計情報を削除できます。成功した場合、メッセージには削除された統計の数が示されます。統計がなかった場合は、"削除するものがありません" というメッセージが表示されます。正常に削除できなかった場合は、エラー・メッセージが表示されます。
パフォーマンス統計の例
以下の例では、現在のプロセスによって準備されたクエリのメイン・モジュールに関するパフォーマンス統計を収集し (アクション・オプション 2)、その後、exportSQLStats() を使用してパフォーマンス統計をターミナルに表示します。
DO ##class(%SYSTEM.SQL.PTools).clearSQLStatsALL()
DO ##class(%SYSTEM.SQL.PTools).setSQLStatsFlagJob(2)
SET myquery = "SELECT TOP 5 Name,DOB FROM Sample.Person"
SET tStatement = ##class(%SQL.Statement).%New()
SET qStatus = tStatement.%Prepare(myquery)
IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
SET pStatus = ##class(%SYSTEM.SQL.PTools).exportSQLStats("$IO")
IF pStatus'=1 {WRITE "Performance stats display failed:"
DO $System.Status.DisplayError(qStatus) QUIT}
以下の例では、現在のプロセスによって準備されたクエリのすべてのモジュールに関するパフォーマンス統計を収集し (アクション・オプション 3)、その後、埋め込み SQL から exportSQLStats() を呼び出してパフォーマンス統計をターミナルに表示します。
DO ##class(%SYSTEM.SQL.PTools).clearSQLStatsALL()
DO ##class(%SYSTEM.SQL.PTools).setSQLStatsFlagJob(3)
SET myquery = "SELECT TOP 5 Name,DOB FROM Sample.Person"
SET tStatement = ##class(%SQL.Statement).%New()
SET qStatus = tStatement.%Prepare(myquery)
IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
&sql(CALL %SYSTEM_SQL.PTools_exportSQLStats('$IO'))
以下の例では、現在のプロセスによって準備されたクエリのメイン・モジュールに関するパフォーマンス統計を収集し (アクション・オプション 2)、その後、StatsSQLViewOpens in a new tab クエリを使用してこれらの統計を表示します。
DO ##class(%SYSTEM.SQL.PTools).clearSQLStatsALL()
DO ##class(%SYSTEM.SQL.PTools).setSQLStatsFlagJob(2)
SET myquery = "SELECT TOP 5 Name,DOB FROM Sample.Person"
SET tStatement = ##class(%SQL.Statement).%New()
SET qStatus = tStatement.%Prepare(myquery)
IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
GetStats
SET qStatus = tStatement.%Prepare("SELECT * FROM %SYS_PTools.StatsSQLView")
IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
SET rsstats = tStatement.%Execute()
DO rsstats.%Display()
WRITE !!,"End of SQL Statistics"
以下の例では、USER ネームスペースのすべてのクエリのすべてのモジュールに関するパフォーマンス統計を収集します (アクション・オプション 3)。1 分後に統計の収集時間が経過すると、アクション・オプション 2 にリセットされ、収集の範囲は、すべてのネームスペースで既定値の 15 (すべての統計) に設定されます。
DO ##class(%SYSTEM.SQL.PTools).clearSQLStatsALL("USER")
DO ##class(%SYSTEM.SQL.PTools).setSQLStatsFlagByNS("USER",3,,7,"M:1:2")
SET myquery = "SELECT TOP 5 Name,DOB FROM Sample.Person"
SET tStatement = ##class(%SQL.Statement).%New()
SET qStatus = tStatement.%Prepare(myquery)
IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
GetStats
SET qStatus = tStatement.%Prepare("SELECT * FROM %SYS_PTools.StatsSQLView")
IF qStatus'=1 {WRITE "%Prepare failed:" DO $System.Status.DisplayError(qStatus) QUIT}
SET rsstats = tStatement.%Execute()
DO rsstats.%Display()
WRITE !!,"End of SQL Statistics",!
TerminateResetStats
WRITE "returns: ",##class(%SYSTEM.SQL.PTools).getSQLStatsFlag(),!
HANG 100
WRITE "reset to: ",##class(%SYSTEM.SQL.PTools).getSQLStatsFlag()