Skip to main content

This documentation is for an older version of this product. See the latest version of this content.Opens in a new tab

SQL クエリ・プランの解釈

この章では、システムで生成された InterSystems SQL クエリ・プランを読み解く方法について説明します。これらのプランの確認で使用できる各種ツールを紹介し、その表示内容を解釈する方法も取り上げます。

SQL クエリをコンパイルすると、そのクエリで指定したデータにアクセスする命令とそのデータを返す命令が生成されます。それらの命令およびその命令の実行シーケンスは、そのクエリに含まれるテーブルの構造や内容に関する SQL コンパイラの所有データの影響を受けます。コンパイラは、テーブル・サイズや使用可能なインデックスなどの情報を使用して、その一連の命令をできる限り効率化しようとします。

クエリ・アクセス・プラン (プラン表示) は、その命令の結果セットを人が読める形式に変換したものです。クエリの設計者はこのクエリ・アクセス・プランを使用して、データへのアクセスがどのように行われるかを確認することができます。SQL コンパイラは、クエリによる指定に従って、データを最も効率的に使用できるようにしようとします。格納されているデータの特定の側面については、コンパイラよりもユーザの方が詳しいことがあります。その場合は、クエリ・プランを利用して、クエリのコンパイラにより多くの情報やガイダンスを提供できるように元のクエリを変更できます。

プランの表示

EXPLAIN ツールまたは [プラン表示] ツールを使用して、SELECTDECLAREUPDATEDELETETRUNCATE TABLE の各操作と、一部の INSERT 操作の実行プランを表示できます。これらは、実行の一環として SELECT を使用するため、総称してクエリ操作と呼びます。InterSystems IRIS では、実行プランは、クエリ操作が準備されたときに生成されます。実行プランを生成するために、実際にクエリを実行する必要はありません。

これらのツールには既定で、InterSystems IRIS が最適であると見なしたクエリ・プランの内容が表示されます。ほとんどのクエリには、有効なクエリ・プランが複数存在します。InterSystems IRIS が最適であると見なしたクエリ・プランに加えて、代替クエリ実行プランを生成および表示することもできます。

InterSystems IRIS には、以下のクエリ・プラン・ツールが用意されています。

  • SQL EXPLAIN コマンド。このコマンドを使用すると、XML 形式のクエリ・プランと、オプションで代替クエリ・プランおよび SQL 統計を生成・表示できます。生成されたすべてのクエリ・プランと統計は、Plan という名前の単一の結果セット・フィールドに含まれます。EXPLAIN コマンドは SELECT クエリでのみ使用できることに注意してください。

  • 管理ポータル→[システムエクスプローラ]SQL インタフェースの [プラン表示] ボタン。

  • 管理ポータル→[システムエクスプローラ][ツール][SQL パフォーマンス・ツール]

  • $SYSTEM.SQL.Explain() メソッド。このメソッドを使用すると、XML 形式のクエリ・プランと、オプションで代替クエリ・プランを生成・表示できます。

  • SQL シェルでシェル・コマンドの SHOW PLANSHOW PLANALT を使用して、最近実行したクエリの実行プランを表示できます。

生成された %PARALLEL クエリおよびシャード・クエリの場合、これらのツールでは、該当するクエリ・プランがすべて表示されます。

EXPLAIN の使用法

以下の例のように EXPLAIN コマンドを実行することでクエリ実行プランを生成できます。

EXPLAIN SELECT TOP 10 Name,DOB FROM Sample.Person

ALT キーワードを使用すると、EXPLAIN コマンドによって代替のクエリ・プランが生成され、返されるクエリ・プランに反映されます。

STAT キーワードを使用すると、EXPLAIN コマンドによってクエリのモジュールごとにパフォーマンス統計が生成されます。モジュールごとに以下の統計が返されます。

  • <ModuleName> : モジュール名。

  • <TimeSpent> : モジュールの総実行時間 (秒単位)。

  • <GlobalRefs> : グローバル参照の数。

  • <LinesOfCode> : コード実行行数。

  • <DiskWait> : ディスク待機時間 (秒単位)。

  • <RowCount> : 結果セット内の行数。

  • <ModuleCount> : このモジュールが実行された回数。

  • <Counter> : このプログラムが実行された回数。

クエリ・プランは XML 形式の文字列で返されます。その最上位のタグは <plans> です。ALT キーワードを指定しない場合、<plans> タグの下位には <plan> タグが 1 つだけ存在します。そのタグの下位には、クエリを指定した <sql> タグ、この特定のプランの相対コストを記述した <cost> タグ、および SQL オプティマイザでクエリがどのように処理されたかの説明があります。ALT キーワードを指定した場合は、<plans> タグの下位に複数の <plan> タグが作成されます。STAT キーワードを指定した場合は、<cost> タグの下位に複数の <stats> タグが存在します。クエリの処理に関連するモジュールごとに別々の <stats> タグが生成されます。

管理ポータルでのプラン表示の使用法

[プラン表示] を使用すると、以下のどの方法でもクエリの実行プランを表示できます。

  • 管理ポータルの [SQL] インタフェースで [システムエクスプローラ][SQL] の順に選択します。ページ上部の [切り替え] オプションでネームスペースを選択します(ユーザごとに管理ポータルの既定ネームスペースを設定できます)。クエリを作成し、[プラン表示] ボタンを押します(一覧表示されているクエリのプラン・オプションをクリックして、[履歴を表示] から [プラン表示] を呼び出すこともできます)。このドキュメントの“管理ポータルの SQL インタフェースの使用法” の章の "SQL 文の実行" を参照してください。

  • 管理ポータルの [ツール] インタフェースで、[システムエクスプローラ][ツール][SQL パフォーマンス・ツール][SQL 実行時統計情報] の順に選択します

    • [クエリのテスト] タブから、ページ上部の [切り替え] オプションでネームスペースを選択します。テキスト・ボックスにクエリを入力します。次に、[SQL 統計によるプラン表示] ボタンを押します。これにより、クエリを実行することなく [プラン表示] を生成します。

    • [統計情報表示] タブで、リストされているいずれかのクエリの [プラン表示] ボタンを押します。リストされるクエリには、[クエリ実行] で記述されたクエリと、[クエリ・テスト] で記述されたクエリの両方が含まれます。

既定では、[プラン表示] は論理モードで値を返します。ただし、管理ポータルまたは SQL Shell から [プラン表示] を呼び出すと、[プラン表示] は実行時モードを使用します。

プランの構造

[プラン表示] の実行プランは、文テキストクエリ・プランの 2 つのコンポーネントで構成されています。

[ステートメント・テキスト] には元のクエリが複製されますが、変更点として、管理ポータルの [SQL] インタフェースにある [プラン表示] ボタンを使用すると、コメントと改行が削除された SQL 文が表示されます。空白は標準化されます。[プラン表示] ボタンは、各リテラルを ? で置換するリテラル置換の実行も表示します。ただし、二重の括弧でリテラル値を囲むことで、リテラル置換を抑制している場合を除きます。Explain() メソッドを使用してプラン表示を表示したときや、[SQL 実行時統計情報] ツールまたは [別のプランを表示] ツールを使用して表示したときには、このような変更は行われません。

[クエリプラン] には、クエリの実行に使用されるプランが示されます。クエリ・プランの内容は以下のとおりです。

  • [Frozen Plan凍結プラン] は、クエリ・プランが凍結されている場合に、[クエリプラン] の先頭行に表示されます。それ以外の場合、先頭行は空白になります。

  • [相対コスト] は、同じクエリの異なる実行プランの効率を比較するための抽象的な数値として、多数の要因から計算される整数値です。この計算では、さまざまな要因の中でも特にクエリの複雑さ、インデックスの有無、およびテーブルのサイズが考慮されます。相対コストは、2 つの異なるクエリの比較には有用ではありません。WHERE 節を指定していない COUNT(*) または MAX(%ID) などの特定の集約クエリによって “Relative cost not available” が返されます。

  • [クエリプラン] は、メイン・モジュールと 1 つ以上のサブコンポーネント (必要な場合) で構成されます。1 つ以上のモジュール・サブコンポーネントが表示される場合は、B から始まるアルファベット順の名前が付けられ (Module:BModule:C など)、実行順にリストされます (アルファベット順とは限りません)。

    既定では、モジュールは処理を実行し、その結果を内部一時ファイル (内部一時テーブル) に入力します。"コメント・オプション" に記載されているように、/*#OPTIONS {"NoTempFile":1} */ を指定することにより、内部一時ファイルを生成しないクエリ・プランを作成するようクエリ・オプティマイザに強制することもできます。

    名前が付いたサブクエリ・モジュールは、クエリ内のサブクエリごとに表示されます。サブクエリ・モジュールには、アルファベット順に名前が付けられます。サブクエリの命名時には、1 つ以上の文字をスキップして各サブクエリに名前が付けられます。アルファベットの最後に達すると、追加のサブクエリには、Z=26 と解析し、同じスキップ・シーケンスを使用して番号が付けられます。例えば、Subquery:F から始まる 2 つおきのサブクエリ命名シーケンスは、F、I、L、O、R、U、X、27、30、33 となります。また、Subquery:G から始まる 1 つおきのサブクエリ命名シーケンスは、G、I、K、M、O、Q、S、U、W、Y、27、29 となります。サブクエリがモジュールを呼び出す場合、そのモジュールは、スキップなしでサブクエリの後にアルファベット順に配置されます。例えば、Subquery:H を指定すると Module:I が呼び出されます。

  • メイン・モジュールの最初の箇条項目が "Read master map" である場合、非効率的なクエリ・プランであることを示しています。クエリ・プランは、Read master map...(使用可能なインデックスがない)、Read index map...(使用可能なインデックスを使用)、または Generate a stream of idkey values using the multi-index combination...(マルチ・インデックス、複数インデックスを使用) のいずれかのマップ・タイプの文で実行を開始します。マスタ・マップは、データのインデックスを読み取るのではなく、データ自体を読み取るため、ほとんどの場合、Read master map... は非効率的なクエリ・プランであることを示しています。テーブルが比較的小さなものでない限り、クエリ・プランを再生成したときに最初のマップに Read index map... と表示されるように、インデックスを定義する必要があります。クエリ・プランの解釈の詳細は、"SQL 実行プランの解釈" を参照してください。

一部の操作では、クエリ・プランが生成されない可能性のあることを示す [プラン表示] が作成されます。

  • 非クエリの INSERT:INSERT... VALUES() コマンドはクエリを実行しません。そのため、クエリ・プランは生成されません。

  • 常に FALSE のクエリ:InterSystems IRIS は、クエリ条件が常に false になるためにデータを返せないクエリを準備している状況を判断できます。この状況は、[プラン表示] の [クエリプラン] コンポーネントで通知されます。例えば、条件 WHERE %ID IS NULL または条件 WHERE Name %STARTSWITH('A') AND Name IS NULL を含むクエリはデータを返せないため、InterSystems IRIS は実行プランを生成しません。実行プランを生成する代わりに、[クエリプラン] は “Output no rows” というメッセージを示します。クエリに、これらの条件のいずれかを指定したサブクエリが含まれている場合、そのサブクエリ・モジュールについての [クエリプラン] には “Subquery result NULL, found no rows” というメッセージが表示されます。この条件チェックは、NULL が関与するいくつかの状況に制限されていて、自己矛盾するクエリ条件のすべてを補足することを意図していません。

  • 不正なクエリ:[プラン表示] には、ほとんどの不正なクエリに対して SQLCODE エラー・メッセージを表示します。ただし、[プラン表示] は空として表示することもあります。例えば、WHERE Name = $$$$$WHERE Name %STARTSWITH('A") (単一引用符と二重引用符に注目してください) などが挙げられます。このような場合、[プラン表示] には [文テキスト] が表示されません。また、[クエリプラン] には [No plan created for this statement] というメッセージが表示されます。一般に、これはリテラルを区切っている引用符が釣り合っていない場合に発生します。また、ユーザ定義 ("外部") 関数に正しい構文を指定しないで、複数のドル記号を先頭に指定した場合にも発生します。

プランの読み取り

プラン表示の結果は、クエリで指定したデータにアクセスして提示するためにどのような処理が実行されるかを示す一連の文です。以下では、プラン表示の文の解釈方法について説明します。

マップへのアクセス

SQL テーブルは、一連のマップとして格納されます。各テーブルには、テーブル内のすべてのデータが含まれたマスタ・マップと、場合によっては、インデックス・マップやビットマップなどのその他のマップがあります。各マップは多次元グローバルとして示すことができます。これには、1 つ以上の添え字の一部のフィールド用のデータと、ノード値に格納された残りのフィールドがあります。添え字はアクセスされるデータを制御します。

  • マスタ・マップでは、通常、RowID フィールドまたは IDKEY フィールドがマップの添え字として使用されます。

  • インデックス・マップでは、通常、他のフィールドが先頭の添え字として使用され、RowID フィールドや IDKEY フィールドは追加の下位レベルの添え字として使用されます。

  • ビットマップでは、ビットマップ・レイヤを追加の RowID の添え字レベルと見なすことができます。ただし、ビットマップは、RowId が正の整数である場合しか使用できません。

クエリのプランはいくつかのテーブルにアクセスする可能性があります。テーブルにアクセスする際、プランは 1 つのマップ (インデックスまたはマスタ・マップ) にアクセスすることも、2 つのマップ (インデックス・マップとそれに続くマスタ・マップ)、あるいは、マルチ・インデックス・プランの場合はいくつかのマップにアクセスすることがあります。

マップを使用したデータへのアクセスでは、プランは使用される添え字を示します。また、実際の添え字値の内容 (添え字に対してテーブルに存在する単一の特定値、一連の特定値、値の範囲、またはすべての値のいずれか) も示します。どれが選択されるかは、クエリで指定されている条件によって異なります。明らかに、アクセスする添え字値が単一もしく少数である方が、その添え字レベルのすべての値にアクセスするよりも速く処理されます。

条件および式

クエリの実行時には、クエリで指定されているさまざまな条件がテストされます。前述のような添え字による制限などの特定の条件を除き、プラン表示では、その出力として条件のテストが明示的に示されることはありません。できるだけ早期に条件をテストすることをお勧めします。多様な条件をテストするために最適な場所は、プランの詳細から推測できます。

同様に、プラン表示では式および部分式の計算の詳細は示されません。簡潔性は別にして、その主な理由はほとんどのデータベース環境で、テーブルおよびインデックスのアクセスが処理にとってより重要な側面となるためです。ディスク・アクセス速度が依然 CPU 処理よりも桁違いに遅いので、テーブル・データの取得にかかる負荷がクエリ全体の負荷の大半を占めています。

ループ

テーブルのデータにアクセスする際は、複数の行を繰り返し検証する必要性が多くなります。そのようなアクセスは、ループによって示されます。受け渡しごとに実行される命令は、ループの本文と呼ばれます。それらはインデントされることによって視覚的に示されます。複数のテーブルが関係するデータベース・アクセスでは、ループ内にループが必要となることが一般的です。この場合、各ループ・レベルは前のレベルからさらにインデントされることによって示されます。

一時ファイル

定義

クエリ・プランは、中間一時ファイル (一時ファイル) を作成して使用する必要性を示す場合もあります。これは、ローカル配列内の “スクラッチ” 領域となります。これは並べ替えなどのさまざまな目的で一時的な結果を保存するのに使用されます。マップと同様に、一時ファイルは 1 つ以上の添え字 (場合によっては、ノード・データも) を使用します。

使用

一時ファイルには、単一テーブルの処理からのデータが含まれる場合があります。この場合、一時ファイルの作成は、そのテーブル内のデータの事前処理と見なされることもあります。そのような一時ファイルの読み取りの後には、ソース・テーブルのマスタ・マップへのアクセスが行われる場合とそうでない場合があります。これ以外の場合、一時ファイルには複数のテーブルの処理の結果が含まれる可能性があります。さらに別の状況では、一時ファイルは分類された集約値の格納や DISTINCT のチェックなどに使用されます。

モジュール

一時ファイルの作成もその他の処理と同じく、モジュールと呼ばれる独立した作業ユニットで行われる場合があります。各モジュールには名前が付けられます。別々のモジュールがリストされている場合、プランは、各モジュールの呼び出し元を示しています。モジュールの実行が終了すると、処理がモジュールの呼び出しの直後の文から再開されます。

処理のために送信されるクエリ

ODBC または JDBC ゲートウェイ接続経由でリンクされた外部テーブルの場合、プランはリモートの SQL ゲートウェイ接続に送信中のクエリのテキストを示し、リモート・テーブルから要求データを取得します。

クエリの並列処理とシャーディングの場合、プランは、並列でまたはシャードで処理するために送信される各種クエリを示します。これらの各クエリに使用されるプランも表示されます。

サブクエリ、JOIN、および UNION

特定のクエリ内のサブクエリ (およびビュー) にも、個別に処理されるものがあります。そのプランは、独立したサブクエリ・セクションで示されます。サブクエリ・セクションの呼び出し元の正確な場所は、プランには示されません。それは、これらが条件または式の処理の一部として呼び出されることが多いためです。

OUTER JOIN を指定するクエリでは、外部結合の意味の要件を満たすために一致する行が見つからない場合に、プランでは NULL の行が生成される可能性が示される場合があります。

UNION の場合は、そのプランに、別個のモジュールにおけるさまざまな UNION のサブクエリからの結果行の組み合わせが示される場合があります (このモジュールでは、それらの結果行のさらなる処理が行われることがあります)。

別のプランを表示

管理ポータルまたは Explain() メソッドを使用して、クエリの代替実行プランを表示できます。

管理ポータルからクエリの代替実行プランを表示するには、以下のいずれかを使用します。

  • [システムエクスプローラ][ツール][SQL パフォーマンス・ツール][代替表示プラン] の順に選択します。

  • [システムエクスプローラ][SQL] の順に選択し、[ツール] ドロップダウン・メニューから [代替表示プラン] を選択します。

[代替表示プラン] ツールを使用して、以下の手順を実行します。

  1. SQL クエリ・テキストを入力するか、[履歴を表示] ボタンを使用して SQL クエリ・テキストを取得します。右側にある [X] の円をクリックすると、クエリ・テキスト・フィールドをクリアできます。

  2. [プラン表示のオプション] ボタンを押して、複数の代替表示プランを表示します。[... をバックグラウンドで実行] チェック・ボックスは、既定ではチェックが外されています。ほとんどのクエリでは、この設定をお勧めします。大規模なクエリや複雑なクエリについては、[... をバックグラウンドで実行] チェック・ボックスにチェックを付けることをお勧めします。長いクエリがバックグラウンドで実行されている間、[プロセス表示] ボタンが表示されます。[プロセス表示] をクリックすると、[プロセス詳細] ページが新しいタブで開きます。[プロセス詳細] ページから、プロセスを参照できます。また、プロセスを一時停止、再開、または終了することもできます。

  3. プランの候補は、マップ・タイプおよび開始マップと共に、コストに基づいて昇順でリストされます。それぞれのプランについて [プラン表示] (統計なし) または [統計付きプランを表示] のリンクを選択すると、詳細を表示できます。

  4. プランの候補のリストから、チェック・ボックスを使用して、比較するプランを選択した後、[プラン表示を統計と比較] ボタンを押してそれらを実行し、それぞれの SQL 統計を表示します。

Explain()Opens in a new tab メソッドと共に all 修飾子を使用すると、1 つのクエリの実行プランがすべて表示されます。InterSystems IRIS が最適 (最小コスト) であると見なしたプランが最初に表示され、続いて代替プランが表示されます。代替プランは、コストの昇順でリストされます。

以下の例は、最適な実行プランを表示してから、代替クエリをリストします。

  DO $SYSTEM.SQL.SetSQLStatsFlagJob(3)
  SET mysql=1
  SET mysql(1)="SELECT TOP 4 Name,DOB FROM Sample.Person ORDER BY Age"
  DO $SYSTEM.SQL.Explain(.mysql,{"all":1},,.plan)
  ZWRITE plan

%SYS.PTools.StatsSQLOpens in a new tab クラス内の possiblePlans メソッドも参照してください。

統計

[プラン表示オプション] リストでは、各代替表示プランに [コスト] 値を割り当てます。この値により、実行プラン間での相対的な比較が可能になります。

[代替表示プラン] の詳細には、[クエリプラン] ごとに [クエリの合計] についての統計 (Stats) のセットが示されます。(該当する場合は) クエリ・プラン・モジュールごとにも、これが示されます。各モジュールの統計には、時間 (全体的なパフォーマンス (秒単位))、グローバル参照 (グローバル参照の数)、コマンド (実行された行の数)、および読み取り待ち時間 (ディスク待機時間 (ミリ秒単位)) が含まれます。[クエリの合計] の統計には、返された行の数も含まれます。

FeedbackOpens in a new tab