模拟Neo4j中的分区

时间:2017-08-08 07:18:40

标签: java neo4j cypher profiling

我尝试使用以下两个查询来测试它以模拟Neo4j(v3.1)中的分区:

Q1: MATCH (a:USER { UID:362})-[:FRIEND]->(b) WHERE b.PARTITION=1 RETURN COUNT(b) Q2: MATCH (a:USER { UID:362})-[:FRIEND]->(b) WHERE b:P1 RETURN COUNT(b)

我希望(也讨论hereQ2会更快,因为它只会检索P1标签而Q1需要在过滤之前检索所有节点。事实证明Q1更快,当我将查询更改为遍历更深度[:FRIEND*1..5]时,这变得更加明显。

修改:UID上有一个索引,PARTITION上没有索引。

使用嵌入式Neo4j的查询计划如下(由于某种原因不显示DBhits)。

Q1

+-------------------+----------------+------------------+-----------------------------+
| Operator          | Estimated Rows | Variables        | Other                       |
+-------------------+----------------+------------------+-----------------------------+
| +ProduceResults   |            191 | COUNT(b)         | COUNT(b)                    |
| |                 +----------------+------------------+-----------------------------+
| +EagerAggregation |            191 | COUNT(b)         |                             |
| |                 +----------------+------------------+-----------------------------+
| +Filter           |          36341 | anon[33], a, b   | b.PARTITION == {  AUTOINT1} |
| |                 +----------------+------------------+-----------------------------+
| +Expand(All)      |         363412 | anon[33], b -- a | (a)-[:FRIEND]->(b)          |
| |                 +----------------+------------------+-----------------------------+
| +Filter           |         105719 | a                | a.UID == {  AUTOINT0}       |
| |                 +----------------+------------------+-----------------------------+
| +NodeByLabelScan  |        1057194 | a                | :USER                       |
+-------------------+----------------+------------------+-----------------------------+

Total database accesses: ?

Q2

+-------------------+----------------+------------------+----------------------------------+
| Operator          | Estimated Rows | Variables        | Other                            |
+-------------------+----------------+------------------+----------------------------------+
| +ProduceResults   |            214 | COUNT(b)         | COUNT(b)                         |
| |                 +----------------+------------------+----------------------------------+
| +EagerAggregation |            214 | COUNT(b)         |                                  |
| |                 +----------------+------------------+----------------------------------+
| +Filter           |          45909 | anon[33], a, b   | a:USER AND a.UID == {  AUTOINT0} |
| |                 +----------------+------------------+----------------------------------+
| +Expand(All)      |         459085 | anon[33], a -- b | (b)<-[:FRIEND]-(a)               |
| |                 +----------------+------------------+----------------------------------+
| +NodeByLabelScan  |         134181 | b                | :P1                              |
+-------------------+----------------+------------------+----------------------------------+

Total database accesses: ?

关于这背后的原因可能是什么想法?

1 个答案:

答案 0 :(得分:1)

首先观察一下:

  1. 它可能没有什么区别(根据查询计划),但是你有没有理由不将Q2写成MATCH (a:USER { UID:362})-[:FRIEND]->(b:P1) RETURN COUNT(b) ?
  2. 用户没有索引或约束吗?
  3. 差异似乎是Q1和Q2选择不同的切入点。 Q1挑选用户,Q2挑选P1,这似乎更有效率。我不会(考虑到计数)期望查询时间有很大差异。 Q1的副作用是您可能通过扫描用户将所有内容加载到内存中。

    如果您真的想加快速度,请在用户(UID)上添加索引。结合P1标签应该真正降低命中数。

    希望这有帮助。

    此致 汤姆