このドキュメントでは、Spanner Graph クエリのパフォーマンスを調整する際のベスト プラクティスについて説明します。これには、次の最適化が含まれます。
- ノードとエッジの入力テーブルの完全スキャンを回避する。
- クエリでストレージから読み取る必要があるデータの量を減らす。
- 中間データのサイズを減らす。
低いカーディナリティのノードから開始する
低いカーディナリティのノードから開始するようにパス トラバーサルを記述します。このアプローチでは、中間結果セットを小さく保ち、クエリの実行を高速化します。
たとえば、次のクエリは同じ意味になります。
フォワード エッジ トラバーサル:
GRAPH FinGraph MATCH (p:Person {name:"Alex"})-[:Owns]->(a:Account {is_blocked: true}) RETURN p.id AS person_id, a.id AS account_id;
リバース エッジ トラバーサル:
GRAPH FinGraph MATCH (a:Account {is_blocked:true})<-[:Owns]-(p:Person {name: "Alex"}) RETURN p.id AS person_id, a.id AS account_id;
Alex
という名前のユーザーがブロックされたアカウントよりも少ない場合、このクエリはフォワード エッジ トラバーサルで記述することをおすすめします。
可変長のパス トラバーサルでは、低いカーディナリティのノードから開始することが特に重要です。次の例は、特定のアカウントから 3 回以内の移動でアカウントを見つける場合の推奨方法を示しています。
GRAPH FinGraph
MATCH (:Account {id: 7})-[:Transfers]->{1,3}(a:Account)
RETURN a.id;
デフォルトですべてのラベルを指定する
ラベルが省略されている場合、Spanner Graph は適格なノードとエッジラベルを推測します。可能であれば、すべてのノードとエッジに対してラベルを指定することをおすすめします。この推定が常に可能とは限らず、スキャンに必要以上のラベルが発生する可能性があるためです。
単一の MATCH ステートメント
次の例では、特定のアカウントから最大 3 回の移動でリンクされているアカウントを検索します。
GRAPH FinGraph
MATCH (src:Account {id: 7})-[:Transfers]->{1,3}(dst:Account)
RETURN dst.id;
複数の MATCH ステートメント
同じ要素を参照していて複数の MATCH
ステートメントにまたがっているノードとエッジにラベルを指定します。
次の例は、この推奨のアプローチを示しています。
GRAPH FinGraph
MATCH (acct:Account {id: 7})-[:Transfers]->{1,3}(other_acct:Account)
RETURN acct, COUNT(DISTINCT other_acct) AS related_accts
GROUP BY acct
NEXT
MATCH (acct:Account)<-[:Owns]-(p:Person)
RETURN p.id AS person, acct.id AS acct, related_accts;