以下查询返回的结果有何不同:
1) MATCH (user)-[:hometown]->(city) MATCH (user)-[:speaks]->(language) RETURN user, city, language
2) MATCH (user)-[:hometown]->(city), (user)-[:speaks]->(language) RETURN user, city, language
3) MATCH (language)<-[:speaks]-(user)-[:hometown]->(city) RETURN user, city, language
4) MATCH (user)-[:hometown]->(city) WITH user,city MATCH (user)-[:speaks]->(language) RETURN user, city, language
如果某些查询返回相同的结果,那么我想知道查询性能差异。
答案 0 :(得分:3)
您可以使用PROFILE
关键字向cypher询问它打算如何执行给定查询。通过这种方式,您可以找出差异并得出哪些更快的结论。
我会做两个问题来向你展示我的意思:
neo4j-sh (?)$ profile MATCH (user)-[:hometown]->(city) MATCH (user)-[:speaks]->(language) RETURN user, city, language;
+------------------------+
| user | city | language |
+------------------------+
+------------------------+
0 row
ColumnFilter
|
+SimplePatternMatcher
|
+TraversalMatcher
+----------------------+------+--------+-----------------------------+-----------------------------------+
| Operator | Rows | DbHits | Identifiers | Other |
+----------------------+------+--------+-----------------------------+-----------------------------------+
| ColumnFilter | 0 | 0 | | keep columns user, city, language |
| SimplePatternMatcher | 0 | 0 | user, language, UNNAMED45 | |
| TraversalMatcher | 0 | 1 | | city, UNNAMED12, city |
+----------------------+------+--------+-----------------------------+-----------------------------------+
这是您的查询#4(稍作调整,因为您的查询#4不按原样运行)
neo4j-sh (?)$ profile MATCH (user)-[:hometown]->(city) WITH user,city MATCH (user)-[:speaks]->(language) RETURN user, city, language;
+------------------------+
| user | city | language |
+------------------------+
+------------------------+
0 row
ColumnFilter(0)
|
+SimplePatternMatcher
|
+ColumnFilter(1)
|
+TraversalMatcher
+----------------------+------+--------+-----------------------------+-----------------------------------+
| Operator | Rows | DbHits | Identifiers | Other |
+----------------------+------+--------+-----------------------------+-----------------------------------+
| ColumnFilter(0) | 0 | 0 | | keep columns user, city, language |
| SimplePatternMatcher | 0 | 0 | user, language, UNNAMED60 | |
| ColumnFilter(1) | 0 | 0 | | keep columns user, city |
| TraversalMatcher | 0 | 1 | | city, UNNAMED12, city |
+----------------------+------+--------+-----------------------------+-----------------------------------+
有很多方法可以比较这些东西,但就要考虑的一般要点而言 - DBhits(以及其他类型的IO)都很慢,因此具有较小数字的查询计划会更好。这些数字对我来说看起来很小,因为我在一个空的数据库上做了这个,它们对你来说会有所不同。
通常,您应该将查询的最具选择性的位推到开头。游戏的名称是考虑更少的数据,并最小化neo4j必须遍历的内容才能找到答案。
考虑这两个问题:它们是彼此的镜像,并返回相同的东西。但其中一个立即具有很强的选择性,而另一个则过于宽泛:
版本1:
match (user {id: 1})
WITH user
MATCH (user)-[:has]->(item)
RETURN item;
第2版:
MATCH (item)
WITH item
MATCH (item)<-[:has]-(user)
WHERE user.id = 1
RETURN item;
我相信一般情况下,版本1会更好。