本文档介绍了优化 Spanner 图查询性能的最佳实践,包括以下优化:
- 避免对节点和边的全表扫描。
- 减少查询需要从存储空间读取的数据量。
- 缩减中间数据的大小。
从基数较低的节点开始
编写路径遍历,使其从基数较低的节点开始。 这种方法可使中间结果集保持较小,并加快查询执行速度。
例如,以下查询具有相同的语义:
正向边缘遍历:
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
的用户数量少于被屏蔽的账号数量,我们建议您在向前边缘遍历中编写此查询。
对于可变长度路径遍历,从基数较低的节点开始尤为重要。以下示例展示了查找与给定账号有三次转账交易的账号的推荐方法。
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;