18.12 PGQL問合せをチューニングするためのベスト・プラクティス
このセクションでは、メモリー割当て、並列度および問合せ計画に関するベスト・プラクティスについて説明します。
- メモリー割当て
グラフ・サーバー(PGX)にはon-heap
およびoff-heap
メモリーがあり、前者は標準JVMヒープですが、後者はPGXによって管理される別のヒープです。グラフ・データと同様に、PGQL問合せの中間結果および最終結果は、一部がオンヒープおよび一部がオフヒープで格納されます。したがって、両方のヒープが必要です。 - 並列度
デフォルトでは、使用可能なすべてのプロセッサ・スレッドがPGQL問合せの処理に使用されます。ただし、必要に応じてグラフ・サーバー(PGX)のparallelism
オプションを設定することにより、スレッドの数を制限できます。 - 問合せ計画の説明
PgxGraph.explainPgql(String query)
メソッドは、問合せの問合せ計画を把握するために使用されます。このメソッドは、次のメソッドを持つOperation (package oracle.pgx.api)
のインスタンスを返します。
親トピック: グラフ・サーバー(PGX)に対するPGQL問合せの実行
18.12.1 メモリー割当て
グラフ・サーバー(PGX)にはon-heap
およびoff-heap
メモリーがあり、前者は標準JVMヒープですが、後者はPGXによって管理される別のヒープです。グラフ・データと同様に、PGQL問合せの中間結果および最終結果は、一部がオンヒープおよび一部がオフヒープで格納されます。したがって、両方のヒープが必要です。
オンヒープ・メモリーの場合、JVMの起動時にデフォルトの最大値が選択されますが、-Xmx
オプションを介して上書きできます。
オフヒープの場合、デフォルトでは最大値は設定されず、オフヒープのメモリー使用量はシステム・リソースを使い果たすまで自動的に増加し続けます。システム・リソースがなくなると、操作が取り消され、メモリーが解放され、適切な例外がユーザーに渡されます。必要に応じて、グラフ・サーバー(PGX)のmax_off_heap_size
オプションを介して最大オフヒープ・サイズを構成できます。
可能なかぎり最大のグラフをロードして問合せを実行できるようにするための適切な開始点として、オンヒープ・とオフヒープの比率を1対1にすることをお薦めします。オンヒープ・メモリー・サイズを構成するステップは、「オンヒープ制限の構成」を参照してください。
18.12.2 並列度
デフォルトでは、使用可能なすべてのプロセッサ・スレッドがPGQL問合せの処理に使用されます。ただし、必要に応じてグラフ・サーバー(PGX)のparallelism
オプションを設定することにより、スレッドの数を制限できます。
グラフ・サーバーの構成パラメータの詳細は、グラフ・サーバー(PGX)エンジンの構成パラメータを参照してください。
18.12.3 問合せ計画の説明
PgxGraph.explainPgql(String query)
メソッドは、問合せの問合せ計画を把握するために使用されます。このメソッドは、次のメソッドを持つOperation (package oracle.pgx.api)
のインスタンスを返します。
print()
: 操作とその子操作を出力するためgetOperationType()
: 操作のタイプを取得するためgetPatternInfo()
: 操作の文字列表現を取得するためgetCostEstimate()
: 操作のコストを取得するためgetTotalCostEstimate()
: 操作とその子操作のコストを取得するためgetCardinatlityEstimate()
: 予想される結果行数を取得するためgetChildren()
: 子操作にアクセスするため
次のケースについて検討します。
g.explainPgql("SELECT COUNT(*) FROM MATCH (n) -[e1]-> (m) -[e2]-> (o)").print()
\--- GROUP BY GroupBy {"cardinality":"42", "cost":"42", "accumulatedCost":"58.1"}
\--- (m) -[e2]-> (o) NeighborMatch {"cardinality":"3.12", "cost":"3.12", "accumulatedCost":"16.1"}
\--- (n) -[e1]-> (m) NeighborMatch {"cardinality":"5", "cost":"5", "accumulatedCost":"13"}
\--- (n) RootVertexMatch {"cardinality":"8", "cost":"8", "accumulatedCost":"8"}
前述の例では、print()
メソッドを使用して問合せ計画を出力しています。
問合せ計画が最適でない場合、パフォーマンスを向上させるために問合せを書き直せることがよくあります。たとえば、合計実行時間を改善する方法として、SELECT
問合せをUPDATE
およびSELECT
問合せに分割できます。
グラフ・サーバー(PGX)はヒント・メカニズムを提供していないことに注意してください。
また、問合せ計画を出力すると、問合せで使用されているフィルタが表示されます。たとえば:
g.explainPgql("SELECT id(n) FROM MATCH (n)-[e]->(m) WHERE " +
...> "id(n) > 500 " +
...> "AND id(n) < 510 " +
...> "AND id(n) <> 509 " +
...> "AND id(n) <> 507 ").print()
\--- Projection {"cardinality":"146", "cost":"0", "accumulatedCost":"175"}
\--- (n) -[e]-> (m) NeighborMatch {"cardinality":"146", "cost":"146", "accumulatedCost":"175"}
\--- (n) RootVertexMatch {"cardinality":"29.2", "cost":"29.2", "accumulatedCost":"29.2"}
WHERE $filter1
filter1: (id(n) <> 509) AND
(id(n) <> 507) AND
(id(n) > 500) AND
(id(n) < 510)
前述の例では、問合せに3行を超えるフィルタがあるため、フィルタは問合せ計画の下に表示されます。フィルタが3行以下の場合、次のようにフィルタは問合せ計画ツリー内に直接表示されます。
g.explainPgql("SELECT id(n) FROM MATCH (n)-[e]->(m) WHERE " +
...> "id(n) > 500 " +
...> "AND id(n) < 510 ").print()
\--- Projection {"cardinality":"162", "cost":"0", "accumulatedCost":"194"}
\--- (n) -[e]-> (m) NeighborMatch {"cardinality":"162", "cost":"162", "accumulatedCost":"194"}
\--- (n) RootVertexMatch {"cardinality":"32.4", "cost":"32.4", "accumulatedCost":"32.4"}
WHERE (id(n) > 500) AND
(id(n) < 510)