Cypher不会在没有提示的情况下使用NodeIndexSeek

时间:2018-10-02 16:10:46

标签: neo4j cypher

我通过UNWIND查询(neo4j 3.4.7、30 GB堆,30 GB页面缓存)添加关系:

UNWIND { rels } AS rel
MATCH (a:Locus), (b:Snp)
WHERE a.chr = rel.start_chr AND a.start = rel.start_start AND a.end = rel.start_end AND a.ref = rel.start_ref AND b.sid = rel.end_sid
CREATE (a)-[r:TEST_MAPS]->(b)
SET r = rel.properties

以下是示例参数:

:param rels => [{start_chr: '6', start_start: 93922926, start_end: 93922926, start_ref: 'h37', end_sid: 'rs782706', properties: {source: 'binder_immuno', uuid: 'e2ee1287-9894-4eb4-8ba8-d8adc4959e50'}}]

使用:Snp(sid):Locus(chr, start, end, ref)为属性建立索引。

问题:添加关系非常缓慢。

创建关系时,查询计划者在NodeIndexSeek上使用快速a:Locus,但在NodeIndexScan上使用慢得多的b:Snp(至少慢一个数量级) )。

计划者的选择似乎取决于所使用的标签,即与其他标签以相同的方式添加关系很快并且仅使用NodeIndexSeek

我知道我可以强迫计划者对b:Snp使用搜索。但是,是否有一种方法可以告诉Cypher在索引可用时始终执行查找而不更改查询?

1 个答案:

答案 0 :(得分:1)

Cypher不保证将如何检索信息。执行的计划会根据您正在运行的Neo4j(计划程序)版本以及计划时的内部数据库统计信息而有所不同。

这就是Cypher完全拥有hints的原因。有时内部统计信息会欺骗计划者来决定一个次优的计划。

可能能够获得所需结果的一种方法是在可能的地方内联属性匹配。就像做MATCH (a:Locus), (b:Snp{sid:rel.end_sid})。这不能保证会更改最终计划,但是通常将尽可能多的WHERE移入MATCH部分似乎可以得到更好的计划。 (对于更复杂的查询。对于简单的查询,没有什么区别。里程会根据您所运行的Neo4j版本而有所不同。)

相关问题