コストベースの最適化プロセスの調整

最適化プロセスでは、コストの正確な予測が最も重要です。ここでは、Virtual DataPort によるコスト予測方法の概要および予測の向上に向けたヒントについて説明します。

クエリプランは、データソースにプッシュダウンされる 1 つまたは複数のクエリ、および複数のデータソースに実行されたクエリの結果を組み合わせて変換する一連の後処理操作で構成されます。したがって、プランのコストを予測するには、以下の 2 種類のコストを考慮する必要があります。

  • データソースに対してクエリを実行し、データソースから Virtual DataPort までネットワーク経由で結果を転送するために要するコスト

  • 実行プランに従って実行する後処理操作に要するコスト

以降の 2 つのサブセクションでは、これらの各コスト要素を Virtual DataPort で予測する方法および適切な予測のために必要な情報に関する基本を説明します。続く各節では、これらの情報を自動的に取得できない具体的な状況で情報を得るための方法について詳しく説明します。

データソースに対するクエリの実行に要するコストの予測

データソースにサブクエリを実行する際に要するコストには、主に以下の 2 つの要素があります。

  • データソースでクエリを処理するために要するコストの予測値。主に考慮する要因は、データソースで実行することが予測される I/O 操作数です。

  • 取得した結果をネットワーク経由で転送するために要するコストの予測値。このコストに影響する主な要因は結果セットのサイズです。

したがって、Virtual DataPort でコストを予測するには以下の情報が必要です。

  • ビューの統計情報: 必要な I/O 操作数とネットワーク転送コストの両方を適切に予測するには、データソースに対するクエリで使用するビューについて、少なくとも以下の統計情報が用意されている必要があります。

    • ビューに存在する行の総数。

    • クエリで使用するビューにあるすべてのフィールドの統計情報。実行するクエリ自体では参照していないフィールドであっても、下位のビューで必要であることも考えられます。

    • これらのフィールドについては、少なくとも個別の値の数を指定する必要があります。

  • クエリで使用可能なインデックスとそのタイプ: Virtual DataPort では、ビューで定義されているインデックスを調べ、それをクエリに適用するかどうかを判断します。つづいて、さまざまな式を使用し、インデックスのタイプに応じて I/O 操作数を予測します。

    インデックスが適用可能かどうか、およびインデックスのタイプに応じて、I/O 操作数が大幅に変化することがあります。したがって、適切な予測を実現するには、正確なインデックス情報を確保する必要があります。

    Virtual DataPort サーバーでは、大半のデータベースで使用可能なインデックスとそのタイプが自動的にイントロスペクションされますが、管理者によるインデックス情報の変更が必要になる場合もあります (以降の「 インデックスの指定 」を参照)。

  • データソースの I/O パラメーター: データソースの I/O パラメーターのいくつかによって、I/O 操作数が大幅に変化することがあります。Virtual DataPort には、広く使用されているデータソースできわめて標準的な構成に適したデフォルト値が用意されていますが、必要に応じてそれらのパラメーターを変更することもできます (「 データソースの I/O パラメーター 」を参照)。

後処理コストの予測

Virtual DataPort では、複数のデータソースに送信されたサブクエリの結果を取得した後、クエリプランの指定に従ってそれらを変換して結合することによって、クエリの結果を取得します。

このコストを予測するには一定の数式が使用されますが、どの数式が使用されるかは、必要な後処理操作 (結合、集計、選択など)、および各操作で入力として受け取り、出力として生成する行数 (とそのサイズ) の予測値に応じて決まります。

Virtual DataPort では、コストベースの最適化を適用できるように、データソースに全体がプッシュダウンされるすべてのビュー (リーフ ビュー) の統計情報を最低限取得する必要があります。それでも、状況によっては、より正確な予測を得るために、他の派生ビューの統計情報も取得することが推奨されます。

  • フラット化ビュー: ビューにフラット化操作を適用すると、得られるビューのスキーマが大幅に変化することがあります。また、ソースビューの各行から出力ビューに複数の行が生成されることもあります。したがって、ソースビューの統計情報から派生ビューの統計情報を予測することはできません。そのため、派生ビューについても、基本ビューの場合と同様の検討手順に従って統計情報を収集することが推奨されます。

  • 派生属性: ビューで式 (SELECT CONCAT(attr1, attr2) AS attr3 ... など) から新しい派生フィールドを作成する場合、新しいフィールドの統計情報を収集または指定することが推奨されます。特に、そのフィールドを選択条件で頻繁に使用する場合に重要です。そうしない場合、デフォルト値が統計情報であると見なされます。

インデックスの指定

データソースに設定されたインデックスを表すインデックスを基本ビューに宣言できます。「 データソースに対するクエリの実行に要するコストの予測 」の説明にあるように、コストベースの最適化では、この情報を使用して、データソースに送信するクエリのコストが予測されます。

Virtual DataPort では、以下のタイプのインデックスが考慮されます。

  • クラスター化インデックス: ディスク上でテーブルの行が特定のフィールドの値に従って並べ替えられている場合、そのフィールドのインデックスをクラスター化インデックスと呼びます。クラスター化インデックスを使用することで、それを適用可能なほとんどのクエリのコストを大幅に削減できます。

  • ハッシュインデックス: 非クラスター化インデックスの一種であり、等価条件と非等価条件での使用に限られますが、他のタイプの非クラスター化インデックスより高速なアクセスを実現できる可能性があります。一般的に、返される行数がテーブルの総行数よりはるかに少ない場合に限り、非クラスター化インデックスを使用することで、クエリの実行時間を大幅に短縮できる可能性があります。

  • その他のインデックス: B ツリーインデックスなど、他のタイプの非クラスター化インデックスを指します。

Virtual DataPort によってクエリがデータソースにプッシュダウンされる場合、ビューで宣言されているインデックスの中にクエリに適用可能なものがあるかどうかが判断され、コストの予測でそのインデックスが考慮されます。

特に大規模なテーブルの場合、クエリに適用可能なインデックスのタイプによってクエリの実行時間が大幅に変化することが考えられます。したがって、インデックスに関する情報が正しいことは不可欠です。

Virtual DataPort では、サポート対象のデータベースに設定されているインデックスが自動的にイントロスペクションされますが、イントロスペクションを経た情報を手動で変更することが推奨される状況もあります。データベース以外のデータソースを扱う場合は、可能な範囲でこのような情報を手動で追加することも推奨されます。具体的なデータベースの詳細については、これに続く節を参照してください。基本ビューのインデックス情報を編集する手順については、「 基本ビューのインデックスの定義 」を参照してください。

Oracle からインポートしたインデックス情報の調整

Oracle では、クラスター化インデックスと非クラスター化インデックスが明確に区別されていません。ディスク上の行の順序とインデックスの値の順序がどの程度一致しているかを示す「クラスター化係数」が、すべてのインデックスに設定されています。

通常は、コスト最適化に使用するために「クラスター化」されていると見なすことができる高度にクラスター化されたインデックスが、テーブルごとに 1 つずつ存在します。多くの場合、プライマリキーフィールドのインデックスが、このようなインデックスに該当します。

JDBC Oracle ドライバーでは、すべてのインデックスがクラスター化インデックスであるとされています 。したがって、より適切なコスト予測を実現するには、基本ビューのインデックスのうち、1 つがクラスタータイプのインデックス、他のすべてのインデックスがその他のタイプのインデックスになるように、基本ビューのインデックス情報を手動で変更する必要があります。

実状として、Oracle にはクラスター化インデックスと実質的に等価な概念である索引構成表というテーブルが存在します。このタイプのテーブルのインデックスは、クラスター化インデックスとして正しくインポートされます。この場合、それ以上の処理は必要ありません。

MySQL からインポートしたインデックス情報の調整

MySQL では、すべての InnoDB テーブルにクラスター化インデックスが 1 つずつ存在します。テーブルにプライマリキーがあれば、それがプライマリキーインデックスです。テーブルにプライマリキーが定義されていない場合は、 NOT NULL 列のみによる最初の一意のインデックスがあれば、それがプライマリキーとして選択されます。

Virtual DataPort に MySQL テーブルをインポートするときは、そのプライマリキーインデックスがクラスター化インデックスと見なされるので、特別な処理は必要ありません。

テーブルにプライマリキーは存在しないものの、前述の制限を検証する一意のインデックスが存在すれば、それが非クラスター化インデックスとしてインポートされます。この場合、そのインデックスのタイプを手動でクラスター化インデックスに変更する必要があります。

Informix からインポートしたインデックス情報の調整

Informix では、インデックスを「クラスター化」して、そのインデックスで指定した順序でテーブルの行をディスクに保存できます。しかし、Informix JDBC ドライバーでは、そのようなインデックスがその他のインデックスとして公開されます。これらのインデックスのタイプをクラスター化インデックスに変更することが推奨されます。

Teradata からインポートしたインデックス情報の調整

Teradata のほとんどのインデックスのタイプは正しくインポートされます。それでも、インポートした情報の変更が推奨される状況として以下の 2 点があります。

  • Teradata の JDBC ドライバーでは、単一テーブルの結合のインデックスは公開されないのでインポートされません。そのタイプのインデックスが存在するテーブルの場合、それらのインデックスのタイプをその他のインデックスとして手動で宣言することが推奨されます。

  • Teradata の一意のセカンダリインデックスは、ハッシュタイプのインデックスとしてインポートされます。それらのインデックスのいずれかが設定されたフィールドが等価条件で使用されていることがわかっている場合、そのインデックスのタイプをクラスター化インデックスに変更することが推奨されます。

Netezza からインポートしたインデックス情報の調整

Netezza にはインデックスの概念が存在しません。特定の状況で部分的にインデックスと同様に扱うことができるデータストレージ構造は存在しますが、その情報は Netezza JDBC ドライバーで公開されないのでインポートもされません。

それでも、Netezza からインポートした基本ビューに以下のインデックスを追加して、何らかの類似したデータストレージの最適化について Virtual DataPort で把握できるようにすることが推奨されます。

  • テーブルの分散列 (データをパーティションに分割するために使用する列) に、クラスタータイプのインデックスを 1 つ宣言します。

  • Netezza のクラスター化基本テーブルに対応するビューに、クラスター化テーブルのキーを整理するために、Virtual DataPort でクラスタータイプのインデックスを 1 つ宣言します。

Redshift からインポートしたインデックス情報の調整

Redshift にはインデックスの概念が存在しません。特定の状況で部分的にインデックスと同様に扱うことができるデータストレージ構造は存在しますが、その情報は Redshift JDBC ドライバーで公開されないのでインポートもされません。

それでも、Redshift からインポートした基本ビューに以下のインデックスを追加して、何らかの類似したデータストレージの最適化について Virtual DataPort で把握できるようにすることが推奨されます。

  • Redshift テーブルの SORTKEY が COMPOUND タイプである場合、そのテーブルにある複数の SORTKEY 列に対してクラスタータイプのインデックスを 1 つ宣言します。Redshift では、COMPOUND タイプの SORTKEY 列によって、ディスク上における行の物理的順序が示されます。したがって、コスト予測では SORTKEY 列によって、通常のクラスター化インデックスの場合と類似の効果が得られます。

  • INTERLEAVED タイプの SORTKEY 列ごとにその他のタイプのインデックスを 1 つずつ宣言します。たとえば、列 col1 と col2 を INTERLEAVED タイプの SORTKEY として設定している場合は、その他のタイプのインデックスを col1 と col2 に 1 つずつ宣言します。

  • Redshift テーブルの分散キーが SORTKEY 列を構成していない場合、その分散キーにその他タイプのインデックスを 1 つ追加します。

SORTKEY と分散キーの詳細については、Redshift のマニュアルを参照してください。

Greenplum からインポートしたインデックス情報の調整

Greenplum JDBC ドライバーではインデックスに関する情報がいっさいエクスポートされないので、Greenplum データベースからインポートした基本ビューには、手動で以下のインデックス情報を追加する必要があります。

  • テーブルの分散列 (データの分割に使用する列) にクラスター化インデックスを 1 つ宣言します。

  • Greenplum のパーティションの定義に使用している列にクラスター化インデックスを 1 つ宣言します。

  • Greenplum の各クラスター化インデックスに使用されている列にクラスター化インデックスを 1 つ宣言します。

  • Greenplum の各非クラスター化インデックスに使用されている列にその他のタイプのインデックスを 1 つ宣言します。

Hive からインポートしたインデックス情報の調整

Hive JDBC ドライバーではインデックスに関する情報がいっさいエクスポートされません。したがって、Virtual DataPort では Hive テーブルに関するインデックス情報がインポートされません。Hive テーブルからインポートした基本ビューには以下のインデックス情報を追加することが推奨されます。

  • テーブルの分散列 (データをパーティションに分割するために使用する列) にクラスター化インデックスを 1 つ宣言します。

  • Hive の各インデックスに使用されている列にその他のタイプのインデックスを 1 つ宣言します。

上記以外のデータソースからインポートしたインデックス情報の調整

これまで説明したデータソース以外のデータソースにはインデックスという概念が存在しません。このようなデータソースとして、Web サービス (REST または SOAP) や SAP BAPI などがあります。それでも、多くの場合、それらのタイプのデータソースは、基盤となるデータベースのフロントエンドとして機能します。その場合、基盤となるデータベースで特定の列にインデックスが指定されていることがわかっているのであれば、そのような情報を該当のビューに追加することが推奨されます。

たとえば、データへのアクセスに使用する多くの Web サービスで基盤となっているデータベースには、Web サービスの操作で必須の入力パラメーターに関連付けられた列にインデックスが設定されています。

データソースの I/O パラメーター

クエリに応答するためにデータソースで実行される I/O 操作の数は、データソースのいくつかの I/O パラメーターの値によって大きく変化することがあります。したがって、コストベースの最適化では、優れた予測を得るためにそれらのパラメーターが考慮されます。そのようなパラメーターとして以下があります。

  • ブロックサイズ: 1 回のランダム I/O 操作によってデータソースとの間で読み書きされるデータ量。多くのデータベースでこの値は 8 ~ 16 KB の範囲ですが、ほとんどは変更可能です。

  • マルチブロックの読み取り数: 多くのデータベースでは、複数のブロックがディスク上で連続している場合、それらが 1 回の I/O 操作で読み取られます (テーブルのフルスキャンを実行する場合やインデックスを読み取る場合など)。このパラメーターは、そのような場合に 1 回の I/O 操作で読み取られる連続ブロックの数を示します。この値はデータベースによって異なりますが、通常は 8 または 9 です。Oracle などの特定のデータベースでは、データベース管理者が手動で変更できます。

Virtual DataPort には、広く使用されているデータソースで頻繁に使用される構成に適切なデフォルト設定が用意されています。ただし、実際のデータベースでその製造元が設定したデフォルト値と大きく異なる設定を使用している場合は、該当の Virtual DataPort データソースで、その設定に応じてそれらのパラメーターを変更することが推奨されます。そのためには、データソースを編集して、[Source configuration] タブで該当のプロパティの値を変更します。