グラフのインデックス作成の概要

インデックスとそれがDSE Graphのパフォーマンスに与える影響について説明します。

DSE Graphでは、頂点中心インデックスとグローバル・インデックスという2種類のインデックスが実装されます。頂点中心インデックスは、単一頂点に対してローカルかつ固有です。グローバル・インデックスは頂点のラベルとプロパティに対して固有であり、グラフ全体に適用されます。サイズの大きな分散型グラフに対するグラフ探索のパフォーマンスは、すべてのインデックスの影響を受けます。インデックス検索のタイプはパフォーマンスに影響し、どのタイプにもメリットとデメリットがあります。

頂点中心インデックス(VCI)の概要

迅速なグローバル検索のためにグラフ要素とインデックス要素に対してグローバルに適用されるグローバル・インデックスと異なり、頂点中心インデックス(VCI)は特定の頂点に対してローカルに作成されます。VCIは、頂点ラベルの特定のインスタンス(つまり特定の頂点)までクエリーが絞り込まれると使用されます。VCIは、頂点のインシデント・エッジと隣接する頂点を、インシデント・エッジのラベルまたはプロパティに従ってソートし、インデックスを作成します。頂点がクエリーされると、全インシデント・エッジが線形スキャンされるのを防ぐため、頂点のインデックスが問い合わされます。探索の計算量、O(n)からO(1)またはO(log n)に削減することができます。典型的なグラフ探索では多数の頂点が調べられるため、インデックスが問い合わせられない場合に各インシデント・エッジ・スキャンのコストがさらに増加します。

DSE Graphでは、頂点中心インデックスはマテリアライズド・ビュー(MV)として維持されます。マテリアライズド・ビューとは、ベース・テーブル以外のプライマリ・キーに基づくクエリーを提供するためにベース・テーブルから生成されるテーブルのことです。このタイプのインデックスは、ほぼ一意の値のカーディナリティが高い、つまりセレクティビティが高い値での使用に適しています。セレクティビティは、次の式を使用してカーディナリティから導き出されます。
selectivity = ( cardinality / number of rows ) * 100%
一般的に、カーディナリティが低いとセレクティビティも低くなり、カーディナリティが高いとセレクティビティも高くなります。

マテリアライズド・ビューの検索では、データの書き込みによって多少のタイム・ペナルティーが生じますが、レスポンス・タイムはベース・テーブルの検索と同様です。データの書き込みまたは更新がグラフで行われると、グラフ・テーブルとともにMVテーブルでもインデックス情報が更新されます。MVテーブルを使用すると、書き込みレイテンシーが高くなりますが、グラフ探索の読み取りレイテンシーは低くなります。エッジ・インデックスプロパティ・インデックスは頂点中心インデックスです。

頂点中心インデックスは、スーパー・ノード問題の解決にも貢献します。スーパー・ノードとは、他と比べてインシデント・エッジ数が飛躍的に多い頂点のことです。よく使われる例としては、読者のフォロワー数と著名人のフォロワー数の比較、つまり、数百人から数千人のフォロワーと数百万人のフォロワーの比較があります。スーパー・ノードのインデックスをチェックするグラフ探索では、インデックス・テーブルを読み取るだけでも通常より時間がかかります。頂点中心インデックスをパーティション分割頂点テーブル(PVT)とともに使用すると、インデックスを複数のパーティションに格納し、DSEクラスター全体に分散させることができます。頂点のエッジ数が100万個を超える場合は、単一DSEデータベース・テーブルのストレージ制限のため、グラフをパーティション分割することが必要となります。インデックス・テーブルを分散させることも、グラフ探索のレスポンス向上につながります。
注: パーティション分割頂点テーブルは、スーパー・ノードを処理するための実験的機能であり、DSE 5.1で廃止予定となっており、DSE 6.0で削除されます。ただし、スーパー・ノード問題の緩和策としては、データ・モデリング・テクニックの方が現時点で効果的です。

グローバル・インデックスの概要

インデックスは探索のクエリー・パフォーマンスに影響を与える場合があります。グラフ探索の開始点の数を減らすと、クエリー結果のレイテンシーを大幅に短縮できます。探索の最初にグラフ内のすべての頂点をチェックしなければならない場合は、正しい開始点を見つけるためのタイム・ロスが生じます。開始頂点を識別できる場合、この時間は必要となりません。グローバル・インデックスを使用すると、頂点のラベルとプロパティを使用してクエリーの開始位置を識別できるため、クエリーのパフォーマンスが向上します。

DSE Graphのグラフ・インデックスでは、DSEセカンダリ・インデックスまたはDSE Searchインデックスが使用されます。フィルター後の頂点のサブセットに適用されるVCIと異なり、グローバル・インデックスは、指定された頂点ラベルを持つすべての頂点に適用されます。

DSE Graphのセカンダリ・インデックスは、DSEセカンダリ・インデックスと同じ法則に従います。このタイプのインデックスは、カーディナリティの低い値またはセレクティビティの低い値を対象としています。インデックス作成対象の値の数は、数十個から最大で数百個までに収まるべきです。たとえば、国で検索する操作は、セカンダリ・インデックスを使用するのに好適な例です。また、値の照合には等価条件しか使用できず、並べ替えまたは範囲クエリーを値に対して使用することはできません。より複雑な値の照合が必要な場合は、検索インデックスの方が優れた選択肢です。

検索インデックスは、テキスト、数値、地理空間の各インデックスが必要な場合に使用され、DSE Searchに依存します。グラフ・データはDSEデータベース・テーブルに格納されるため、頂点ラベルあたり1個の検索コアを使用可能です。検索でインデックス作成される頂点ラベルごとに、searchという名前の単一の検索インデックスにすべてのプロパティを追加する必要があります。検索はDSE Searchで実装されているため、すべてのデータ型のインデックスを作成できます。全文と文字列という2つのインデックス・オプションでは、インデックス作成結果が異なるため、プロパティ・キーを定義する必要があります。全文インデックスでは、トークン化とセカンダリ・プロセス(大文字・小文字の正規化など)が実行されます。全文インデックスは、テキストの部分一致が必要なクエリーで使用でき、正規表現(regEx)検索に役立ちます。文字列インデックスは、Solrファセット化と似ており、文字列の完全一致が求められ、トークン化が必要とならないクエリーで使用されます。このタイプのインデックスは、セレクティビティが低い場合に最適ですが、あいまい一致に役立ちます。DSE 5.1では、トークン化インデックスと非トークン化インデックスの両方にあいまい検索が追加されています。

複合インデックス・キーは、現時点ではDSE Graphでサポートされていません。

インデックス作成のベスト・プラクティス

同一プロパティに関して複数のインデックスを作成できます。たとえば、マテリアライズド・インデックスと検索インデックスの両方をプロパティamountに関して作成できます。DSE Graphのクエリー最適化ツールは、クエリーの処理時に適切なインデックスを自動的に使用します。使用するインデックス・タイプを指定する機能はありません。パフォーマンスを最大限に高めるため、DSE Graphでは、MCインデックス、セカンダリ・インデックス、DSE Searchインデックスの優先順位で使用されます。セレクティビティに基づいて、プロパティごとに異なるインデックス・タイプを適宜作成できます。複合キーを使用して作成された頂点のインデックス作成については、特別な考慮事項があります。つまり、2つ以上のプロパティをインデックス作成する場合は、検索インデックスが唯一の選択肢となります。このことは、DSE Graph Loaderを使用してグラフを読み込む場合に特に当てはまります。複合キー(カスタム頂点ID)を構成するプロパティ・キーに対して別々のマテリアライズド・ビュー・インデックスは使用されず、DSE Graph Loaderは頂点の作成に失敗します。

一般的に、DSEでの全般的な使用が制限されているのと同じ理由で、DSE Graphのセカンダリ・インデックスは有用性が限られています。マテリアライズド・ビュー・インデックスを検討すべきです。

検索インデックスが作成される場合は、インデックスの構築に時間がかかることと、インデックスが使用可能になるまでは、インデックスに依存するクエリーが失敗する可能性があることに注意してください。検索インデックスを必要とするデータ挿入をスキーマ作成の直後に行うと、アプリケーションでエラーが発生する場合があります。また、検索インデックスを使用するクエリーは、クラスター内のDSE Search対応ノードで実行する必要があります。

検索インデックスにはリソースが必要です。インデックスごとにデフォルトで最小256MBが割り当てられ、インデックスごとに2つの物理コアが必要となります。典型的な32GBノードの場合、検索インデックスの合理的な作成数は16個です。

テキスト述語(regex、tokenRegex、prefix、tokenPrefix、token、eq/neq)を使用するクエリーは、DSE Searchインデックスがないと実行できません。ただし、そのようなクエリーではセカンダリ・インデックスやマテリアライズド・インデックスが使用されず、代わりにフル・グラフ・スキャンを使用して結果が返されます。デフォルトで、実稼働モードではフル・グラフ・スキャンを実行できないため、そのようなクエリーは失敗します。このような照合検索方法が必要な場合は、検索インデックスを使用することが強く推奨されます。
注意: tokenRegexは、検索インデックスが使用されるかどうかにかかわらず、クエリーで大文字・小文字を区別しません。
DSE 5.1以降では、トークン化(TextField)形式と非トークン化(StrField)形式の両方でテキスト検索インデックスがデフォルトで作成されます。つまり、作成されたすべてのテキスト頂点プロパティでどのテキスト述語(token、tokenPrefix、tokenRegex、eq、neq、regex、prefix)でも使用できます。実際的には、asString()メソッドを使用して検索インデックスを作成する必要があるのは、在庫カテゴリ(食卓用金物、靴、衣服)など、トークン化とテキスト解析が絶対に役に立たない場合だけです。複数の文章から成る長い記述など、トークン化されたテキストの検索には、asText()メソッドが役に立ちます。クエリー最適化ツールは、使用されているテキスト述語に基づいて、解析済みインデックスと未解析インデックスのどちらを使用するかを選択します。
注: DSE 5.1より前では、テキスト・プロパティ・データの検索インデックスは、asString()として指定されていない場合にデフォルトでasText()に設定されていました。

検索インデックス・スキーマを編集して、検索特性を変更することが可能です。これらの二次的な変更はDSE Graphによって上書きされませんが、この方法でフィールドの追加または削除は行わず、DSE Graphコマンドのみを使用してください。この機能の一般的な用途は、検索のタイプに大文字・小文字の区別を追加するなど、検索の動作を変更することです。