我正在使用neo4j 2.1.7最近我正在尝试使用Match查询,搜索带有多个标签的节点。我发现,通常是查询
Match (p:A:B) return count(p) as number
和
Match (p:B:A) return count(p) as number
工作的时间不同,特别是在你拥有2百万个节点A和0个节点B的情况下。 那么标签订单效果搜索时间呢?这个未来是否记录在哪里?
答案 0 :(得分:9)
Neo4j在内部维护着一个标签扫描存储 - 它基本上是一个查找,可以快速获取带有定义标签A
的所有节点。
进行类似
的查询时MATCH (n:A:B) return count(n)
labelscanstore用于查找所有A
个节点,然后如果这些节点也带有标签B
,则会对其进行过滤。如果n(A) >> n(B)
MATCH (n:B:A)
提高B
的效率更高,因为您只查找几个PROFILE MATCH (n:A:B) return count(n)
节点并过滤那些节点。
您可以使用create (:A:B);
with 1 as a foreach (x in range(0,1000000) | create (:A));
with 1 as a foreach (x in range(0,100) | create (:B));
查看查询计划。对于Neo4j< = 2.1.x,您将看到不同的查询计划,具体取决于您指定的标签的顺序。
从Neo4j 2.2开始(在撰写本回复时提供里程碑M03),这是一款基于成本的Cypher优化器。现在Cypher知道节点统计信息,它们用于优化查询。
作为一个例子,我使用以下语句创建了一些测试数据:
MATCH (n:B:A) return count(n)
MATCH (n:A:B) return count(n)
我们现在有100个B节点,1M个A节点和1个AB节点。在2.2中这两个陈述:
+------------------+---------------+------+--------+-------------+---------------+
| Operator | EstimatedRows | Rows | DbHits | Identifiers | Other |
+------------------+---------------+------+--------+-------------+---------------+
| EagerAggregation | 3 | 1 | 0 | count(n) | |
| Filter | 12 | 1 | 12 | n | hasLabel(n:A) |
| NodeByLabelScan | 12 | 12 | 13 | n | :B |
+------------------+---------------+------+--------+-------------+---------------+
导致完全相同的查询计划(因此执行速度相同):
B
由于只有少量A
个节点,因此扫描B&C并过滤{{1}}会更便宜。 Smart Cypher,不是吗? - )