Neo4j 2.0.1使用谓词start和match之间的Cypher性能差异



大约一周前开始使用Cypher(真的很喜欢它)。在"浏览器"界面,我运行两个查询:

1) start n=node:Node(name="foo") match (n)-[r*..4]-(m) return n,m
2) match (n{name:"foo"})-[r*..4]-(m) return n,m

第一个查询几乎立即返回,第二个查询超过一个小时,而且还在继续。我天真地认为它们是相等的,但显然不是。我在neo-shell中运行了一个"较小"(路径最多1)的版本,以便我可以分析它们。

profile start n=node:Node(name="foo") match (n)-[r*..1]-(m) return n,m;
ColumnFilter(symKeys=["m", "n", "  UNNAMED51", "r"], returnItemNames=["n", "m"], _rows=4, _db_hits=0)
TraversalMatcher(start={"expr": "Literal(foo)", "identifiers": ["n"], "key": "Literal(name)",
"idxName": "Node", "producer": "NodeByIndex"}, trail="(n)-[*1..1]-(m)", _rows=4, _db_hits=5)

.

profile match (n{name:"foo"})-[r*..1]-(m) return n,m
ColumnFilter(symKeys=["n", "m", "  UNNAMED33", "r"], returnItemNames=["n", "m"], _rows=4, _db_hits=0)
Filter(pred="Property(n,name(0)) == Literal(foo)", _rows=4, _db_hits=196870)
TraversalMatcher(start={"producer": "AllNodes", "identifiers": ["m"]}, 
trail="(m)-[*1..1]-(n)", _rows=196870, _db_hits=396980)

从其他stackoverflow问题中我了解到db_hits很好看,所以看起来第二个查询基本上已经完成了线性扫描(我的db几乎是400k节点)。这一点似乎可以从"AllNodes"的"producer"值而不是"NodeByIndex"得到证实。

显然,我需要以不同的方式指定匹配(谓词),以便它命中索引。索引在参数"name"上称为"Node"。我的google和stacko搜索让我很失望。如何在匹配中指定条件,使其命中索引?

更新: 经过一番调查,似乎我使用的是"遗留"索引?然后尝试使用"new style(不要使用start)"查询来达到这个目的…(有点外推)。所以我可以这样做:

create index ON :label(name)

,这将为name属性上的特定标签提供索引,但我真正想要的是所有节点名称上的索引(我猜是非遗留索引)。在我的一些用例中,这很重要(用户可能不知道标签,但知道名称)。

目前还没有全局模式索引,所以您可能希望在通用标签(如EntityNode)上创建索引,并创建如下索引:

create index on :Entity(name);

并将Entity标签添加到所有节点。

match (n) set n:Entity;

最新更新