我很好奇过滤器在neo4j查询中的工作原理。它们导致db命中(根据PROFILE),似乎他们不应该。
示例查询:
PROFILE MATCH (a:act)<-[r:relationship]-(n)
WHERE a.chapter='13' and a.year='2009'
RETURN r, n
act
属性的标签chapter
上创建了一个索引)返回6行。a.year == {AUTOSTRING1}
导致12 db命中。如果在早期的数据库读取中已经获取了a
的6个匹配实例,为什么它需要执行任何数据库命中,不应该只是过滤它们而不需要返回更多db读取?
我意识到我等同于db命中&#39;用&db;读取&#39;在这里,这可能不准确。如果没有,那么&db; db命中&#39;
究竟是什么?最后,过滤器产生的db命中数似乎大致匹配:
<number of filtering elements> * 2 * <number of already queried nodes to filter on>
其中&#39;过滤元素的数量&#39;是提供的过滤器数量,即
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)&lt; - [r:CHILD_OF] - (n) 在哪里a.chapter =&#39; 13&#39;和a.year =&#39; 2009&#39; 返回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)&lt; - [r:CHILD_OF] - (n) 在哪里a.chapter =&#39; 13&#39;和a.year =&#39; 2009&#39; 返回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: ?
答案 0 :(得分:1)
因为读取节点(记录)和读取属性(记录)不是相同的db操作。
你是对的,过滤器命中应该最多为6。 通常Neo4j会在最早的时刻提取过滤器和谓词,因此它应该在索引查找后直接过滤。
在某些情况下(由于谓词)它只能在找到路径后进行过滤,然后db-hits的数量可能等于检查路径的数量。
您使用的是哪个Neo4j版本?你能分享一下完整的查询计划吗?