Neo4j Cypher 1.9.5查询速度超过2个索引

时间:2013-12-18 05:28:21

标签: indexing neo4j cypher

我在Neo4j中有一个Cypher 1.9.5查询,当用三个索引执行时,它就会挂起。如果我改变查询以使用两个索引和where子句,那么它可以工作(仍然很慢!)

在这个改变的样本中,我正在寻找名称以'tc_'开头的玩具,名称以'2'开头的小盒子,而小盒子的名字以'p'开头

有3个索引挂起

START b=node:BigBox('name:p*'), s=node:SmallBox('name:2*'), ts=node:Toys('name:tc_*')
MATCH b-[:SMALLBOX]->s, s-[:TOYS]->ts
RETURN count(ts)

但这些工作

START s=node:SmallBox('name:2*'), ts=node:Toys('name:tc_*')
MATCH b-[:SMALLBOX]->s, s-[:TOYS]->ts
WHERE b.name =~ '(?i)p.*'
RETURN count(ts)

START b=node:BigBox('name:p*'), ts=node:Toys('name:tc_*')
MATCH b-[:SMALLBOX]->s, s-[:TOYS]->ts
WHERE s.name =~ '(?i)2.*'
RETURN count(ts)

最后两个给出了第一个答案。

START子句中允许两个以上的索引需要做什么?请注意,我在90-100个小盒子中有超过200,000个玩具,而这些小盒子又分为5个大盒子。

1 个答案:

答案 0 :(得分:3)

你犯了一种叫做笛卡尔积的罪。

正在发生的事情是你正在获取索引查找的所有三组结果:bsts,并且对于每个b,它会找到所有s的结果,对于每组b + s,它找到了所有的b + s + ts。然后,对于每个组合,它找到一个匹配。

解决此问题的更好方法是选择start子句中的最小集合b,然后使用遍历来查找匹配的潜在sts 。所以:

START b=node:BigBox('name:p*')
MATCH b-[:SMALLBOX]->s
WHERE s.name =~ "2.*" 
WITH b, s
MATCH s-[:TOYS]->ts
WHERE ts.name =~ "tc_.*"
RETURN count(ts)