首页 > 解决方案 > Neo4j - 为什么探查器在全扫描节点的情况下只显示 2000003 db 命中?

问题描述

我想了解为什么查询探查器只显示2000003db hits。毕竟,查询需要在节点上进行全扫描。

我的问题是关于以下查询:

WITH ["Jennifer","Michelle","Tanya","Julie","Christie","Sophie","Amanda","Khloe","Sarah","Kaylee"] AS names 
    FOREACH (r IN range(0,1000000) | CREATE (:LabelA {username:names[r % size(names)]+r}))

WITH ["Jennifer","Michelle","Tanya","Julie","Christie","Sophie","Amanda","Khloe","Sarah","Kaylee"] AS names 
    FOREACH (r IN range(0,1000000) | CREATE (:LabelA:LabelB {username:names[r % size(names)]+r}))

WITH ["Jennifer","Michelle","Tanya","Julie","Christie","Sophie","Amanda","Khloe","Sarah","Kaylee"] AS names 
    FOREACH (r IN range(0,1000000) | CREATE (:LabelB {username:names[r % size(names)]+r}))

MATCH (n:LabelA:LabelB) RETURN COUNT(n)

它创建3000003节点。因此,为了计算具有特定标签的节点数,我们应该进行全扫描,这样3000003db 就会命中。但是,配置文件显示,在第一步中它需要2000003数据库命中。怎么可能?

借自:

https://maxdemarzi.com/2017/10/25/counting-nodes-with-multiple-labels/

标签: neo4jcypher

解决方案


标签是自动索引的。这意味着,对于标签 LA 和 LB,Neo4j 内部有一个带有 LA 标签的所有节点的列表,以及另一个带有 LB 标签的所有节点的列表。

所以全扫描只需要扫描那两个索引。实际上,它只需要扫描其中一个,并检查每个节点是否有第二个标签。

此外,“db hit”实际上并不是数据库读取。它实际上是一个抽象的“数据库时间单位”。因此,将其更像是对所用系统 IO 时间的通用度量。(这在具有复杂过滤器的复杂查询中更为显着。例如子字符串匹配,或查找值为“x”的任何 node.property)(https://neo4j.com/docs/developer-manual/current/cypher/execution -plans/#execution-plans-dbhits )


推荐阅读