Neo4j技术疑问:全量扫描节点为何查询分析器仅显示2000003次DB Hits?
为啥Neo4j查询分析器只显示2000003次db 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 {username:names[r % size(names)]+r}))
我来帮你拆解清楚这个问题:
先看你的查询实际执行了多少写入操作
你用了两个FOREACH循环,每个循环依赖range(0, 1000000)生成序列——这里要注意,Neo4j的range(start, end)是包含首尾值的,所以每个循环会执行1000001次CREATE操作,两个循环下来总共创建1000001 * 2 = 2000002个LabelA节点。
再聊Neo4j的db hits计数逻辑
db hits统计的是查询执行过程中对数据库存储层的实际读写访问次数,但不是所有操作都会被计入:
- 每创建一个新节点,会产生1次db hit(因为要把新节点写入磁盘存储),这部分就占了2000002次。
- 像数组取值、
size(names)计算、取模r % size(names)这些操作,都是在内存里完成的,根本不会碰底层存储,所以不会产生db hits。 - 剩下的1次db hits,大概率是查询收尾阶段的事务相关存储操作(比如事务提交时的少量校验操作),加起来刚好是你看到的2000003次。
关于“全量扫描”的误解
你提到查询需要全量扫描,但其实你的CREATE语句完全不需要扫描任何现有节点:
- 全量扫描一般出现在
MATCH语句没有可用索引的时候(比如MATCH (n:LabelA)没建索引,就会扫描所有LabelA节点)。 - 而
CREATE是直接写入新节点,不需要读取或扫描已有的数据,自然不会产生全量扫描对应的db hits。
如果你的完整查询里确实包含全量扫描逻辑(比如创建完节点后又写了MATCH (n:LabelA)这类语句),那得结合完整语句再分析,但单从你给出的创建语句来看,这个db hits的计数完全合理。
内容的提问来源于stack exchange,提问作者CypherFancy
相关产品推荐
相关产品推荐

