このドキュメントでは、Spanner Graph クエリのパフォーマンスをチューニングするためのベスト プラクティスについて説明します。これには、次の最適化が含まれます。
- ノードとエッジの入力テーブルの完全スキャンを回避します。
- クエリでストレージから読み取る必要があるデータの量を減らします。
- 中間データのサイズを減らします。
カーディナリティの低いノードから開始する
カーディナリティの低いノードから開始するようにパス トラバーサルを記述します。このアプローチでは、中間結果セットを小さく保ち、クエリの実行を高速化できます。
たとえば、次のクエリのセマンティクスは同じです。
フォワード エッジ トラバーサル:
GRAPH FinGraph MATCH (p:Person)-[:Owns]->(a:Account) WHERE p.name = "Alex" AND a.is_blocked RETURN p.id AS person_id, a.id AS account_id;
リバース エッジ トラバーサル:
GRAPH FinGraph MATCH (a:Account)<-[:Owns]-(p:Person) WHERE p.name = "Alex" AND a.is_blocked 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;