【问题标题】:Simulating partitions in Neo4j在 Neo4j 中模拟分区
【发布时间】:2017-08-08 07:18:40
【问题描述】:

我试图用以下两个查询来测试这个以模拟 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: ?

对这背后的原因有什么想法吗?

【问题讨论】:

    标签: java neo4j cypher profiling


    【解决方案1】:

    先观察几个:

    1. 它可能没有什么不同(考虑到查询计划),但有没有理由你不把 Q2 写成MATCH (a:USER { UID:362})-[:FRIEND]-&gt;(b:P1) RETURN COUNT(b) ?
    2. 用户的 uid 没有索引或约束?

    区别似乎是 Q1 和 Q2 选择了不同的切入点。 Q1 选择 User,Q2 选择 P1,这似乎更有效。不过,我不会(考虑到计数)期望查询时间会有巨大差异。 Q1 的一个副作用是,您可能会通过对 User 的扫描将所有内容加载到内存中。

    如果您真的想加快速度,请在用户(UID)上放置一个索引。结合 P1 标签,应该会真正降低点击次数。

    希望这会有所帮助。

    问候, 汤姆

    【讨论】:

    • 对不起,我应该提到:1。我也尝试过。它返回完全相同的计划。似乎没有什么区别。 2. uid上有索引。 Q2 选择那个入口点,然后在查询计划中测试 uid 条件是不是很奇怪?
    • 确定是 2 吗?我之所以问,是因为“NodeByLabelScan”表示它正在扫描整个数据库中具有该标签的所有节点。你能做一个简单的查询来验证吗?
    • 哦,谢谢!我刚刚意识到我在 UID 上有一个旧索引,所以我更新了查询以从 START a=node(362) 开始,现在 Q2 比预期的 Q1 稍快。
    猜你喜欢
    • 2013-09-06
    • 2012-12-31
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 2015-05-03
    • 1970-01-01
    相关资源
    最近更新 更多