Neo4J MATCH查询 - 多种方法之间的差异

时间:2015-02-07 15:01:25

标签: neo4j

以下查询返回的结果有何不同:

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

如果某些查询返回相同的结果,那么我想知道查询性能差异。

1 个答案:

答案 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会更好。