neo4j - 分析 neo4j 查询 : filter to db hits

标签 neo4j

我很好奇过滤器在 neo4j 查询中是如何工作的。它们会导致数据库命中(根据 PROFILE),而且它们似乎不应该命中。

查询示例:

PROFILE MATCH (a:act)<-[r:relationship]-(n)
WHERE a.chapter='13' and a.year='2009'
RETURN r, n
  1. NodeIndexSeek:(我在标签 act 上为 chapter 属性创建了一个索引)返回 6 行。
  2. 过滤器:a.year == {AUTOSTRING1} 导致 12 次数据库命中。

如果它已经在早期的数据库读取中获取了 a 的 6 个匹配实例,为什么它需要进行任何数据库命中,难道它不应该只是过滤掉它们而不返回进行更多的数据库读取吗?

我意识到我在这里将“数据库命中”等同于“数据库读取”,这可能不准确。如果不是,“db hits”到底是什么?

最后,过滤器产生的数据库命中数似乎大致匹配:

<number of filtering elements> * 2 * <number of already queried nodes to filter on>

其中'number of filtering elements'是提供的过滤器的数量,即

WHERE a.year='2009' and a.property_x='thing'

是两个元素。

感谢您的帮助。

编辑: 以下是查询中 PROFILE 和 EXPLAIN 的结果。 这只是一个示例查询。我发现了

的行为
filter db hits = <number of filtering elements> * 2 * <number of already queried nodes to filter on>

在我运行的查询中通常是正确的。

PROFILE MATCH (a:act)<-[r:CHILD_OF]-(n) WHERE a.chapter='13' AND a.year='2009' RETURN r, n

8 rows
55 ms

Compiler CYPHER 2.2

Planner COST

Projection
  |
  +Expand(All)
    |
    +Filter
      |
      +NodeIndexSeek

+---------------+---------------+------+--------+-------------+---------------------------+
|      Operator | EstimatedRows | Rows | DbHits | Identifiers |                     Other |
+---------------+---------------+------+--------+-------------+---------------------------+
|    Projection |             1 |    8 |      0 |     a, n, r |                      r; n |
|   Expand(All) |             1 |    8 |      9 |     a, n, r |     (a)<-[r:CHILD_OF]-(n) |
|        Filter |             0 |    1 |     12 |           a | a.year == {  AUTOSTRING1} |
| NodeIndexSeek |             1 |    6 |      7 |           a |             :act(chapter) |
+---------------+---------------+------+--------+-------------+---------------------------+

Total database accesses: 28

EXPLAIN MATCH (a:act)<-[r:CHILD_OF]-(n) WHERE a.chapter='13' AND a.year='2009' RETURN r, n

4 ms

Compiler CYPHER 2.2

Planner COST

Projection
  |
  +Expand(All)
    |
    +Filter
      |
      +NodeIndexSeek

+---------------+---------------+-------------+---------------------------+
|      Operator | EstimatedRows | Identifiers |                     Other |
+---------------+---------------+-------------+---------------------------+
|    Projection |             1 |     a, n, r |                      r; n |
|   Expand(All) |             1 |     a, n, r |     (a)<-[r:CHILD_OF]-(n) |
|        Filter |             0 |           a | a.year == {  AUTOSTRING1} |
| NodeIndexSeek |             1 |           a |             :act(chapter) |
+---------------+---------------+-------------+---------------------------+

Total database accesses: ?

最佳答案

因为读取节点(记录)和读取属性(记录)不是同一个数据库操作。

您说得对,过滤器匹配项最多应为 6。 通常 Neo4j 将过滤器和谓词拉到尽可能早的时刻,因此它应该在索引查找之后直接进行过滤。

虽然在某些情况下(由于谓词)它只能在找到路径后进行过滤,然后 db-hits 的数量可能等于检查路径的数量。

您使用的是哪个 Neo4j 版本?你能分享你的完整查询计划吗?

关于neo4j - 分析 neo4j 查询 : filter to db hits,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31787514/

相关文章:

Neo4j 返回一个带有节点数组的节点作为属性或单独的数组

java - 如何删除neo4j图数据库

ruby-on-rails - 如何删除 Neo4jRB 3.0 中的关系?

maven - 在 neo4j 2.3.1 上安装 neo4j-spatial

Neo4j O'reilly 书籍示例

java - 设置 Spring Data Neo4j 示例

java - 安装 Neo4j REST 服务器插件

java - Java中如何比较和统计多个Streams的元素?

python - 如何获取不相交子图中的所有节点 - neo4j/py2neo

neo4j - 如何使用 spring data 在 Neo4j 中保存和检索嵌套对象