2015-06-05 114 views
3

目前我对Neo4j的2.2.2Neo4j的不使用索引

尝试此查询在这篇文章的时候,我们没有任何标记的节点然而,正如我们最近从1.x的Neo4j的升级所以我们没有选择使用USING子句。

我想使用索引,但结束了全表扫描。

START pfComp=node:Company('id:2403226') , ptComp=node:Company('id:1946633') 
OPTIONAL MATCH 
    (pfComp)<-[c:CHILD_OF*]-(cfComp) 
WITH collect(id(cfComp)) as cfCompIds, ptComp, pfComp 
OPTIONAL MATCH 
       (ptComp)<-[c2:CHILD_OF*]-(ctComp) 
WITH cfCompIds, collect(id(ctComp)) AS ctCompIds 
MATCH 
       (fComp) -[fR:PARTICIPATES_IN]-> cdeals <-[tR:PARTICIPATES_IN]-(tComp) 
WHERE 
       (fComp.id = 2403226 or id(fComp) in cfCompIds) and 
       (tComp.id = 1946633 or id(tComp) in ctCompIds) 
RETURN fComp, tComp, cdeals 

Cypher version:CYPHER 2.2,planner:COST。 1305292总分贝命中79128毫秒。

对此的任何帮助将不胜感激。

以下是完整的配置文件命令输出。

This is the explain plan for the query

查询的开始部分执行快速:

profile START pfComp=node:Company('id:2403226') , ptComp=node:Company('id:1946633') 
OPTIONAL MATCH 
    (pfComp)<-[c:CHILD_OF*]-(cfComp) 
WITH collect(id(cfComp)) as cfCompIds, ptComp, pfComp 
OPTIONAL MATCH 
       (ptComp)<-[c2:CHILD_OF*]-(ctComp) 
return cfCompIds, collect(id(ctComp)) AS ctCompIds 

Cypher支架版本:CYPHER 2.2,计划者:COST。在582毫秒内共有836个数据点击。

enter image description here

+0

也许这里有一个错字?你可以使用你以前没有初始化过的标识符,所以它必须做一个非常糟糕的全面扫描并展开:'OPTIONAL MATCH(ptComp)< - [c2:CHILD_OF *] - (ctComp)' –

+0

这些在这里有不一致的定义方式他们的查找,为财产查找你想念标签和ID()查找冲突与道具查找我会把它分成两个部分的工会 –

+0

迈克尔汉格尔:查询的乞讨部分是好的: 个人资料START pfComp = node:Company('id:2403226'),ptComp = node:Company('id:1946633') OPTIONAL MATCH (pfComp)< - [c:CHILD_OF *] - (cfComp) WITH collect(id (cfComp))作为cfCompIds,ptComp,pfComp 可选匹配 (ptComp)< - [c2:CHILD_OF *] - (ctComp) 返回cfCompIds,collect(id(ctC) omp))AS ctCompIds 结果: Cypher版本:CYPHER 2.2,planner:COST。在582毫秒内共有836个数据点击。 –

回答

2

你的第二个部分看起来像一个关系加入,或额外的查询(如第n + 1选择)。 也许使用图模型呢?查询也变得更简单。

所以你会计算fComptComp与最初的匹配,由于*0..它包括每个pfComp和ptComp。

然后,您将在最后一场比赛中在fComp和tComp之间交叉。

请尝试一下,看看它是如何票价:你

MATCH (pfComp:lCompany)<-[c:CHILD_OF*0..]-(fComp:lCompany) 
WHERE pfComp.id = 2403226 
// reduce cardinality for following match 
WITH collect(distinct fComp) as companies1 
MATCH (ptComp:lCompany)<-[c2:CHILD_OF*]-(tComp:lCompany) 
WHERE ptComp.id = 1946633 
// create cross product between fComp and tComp 
UNWIND companies1 as fComp 
MATCH (fComp) -[fR:PARTICIPATES_IN]->(cdeals)<-[tR:PARTICIPATES_IN]-(tComp) 
RETURN fComp, tComp, cdeals; 
+0

没想到会为此获得更好的性能,但是您将性能提高了3倍。谢谢你,先生。 Cypher版本:CYPHER 2.2,策划者:COST。 40525总分贝命中307毫秒。 –

+0

美好时光!使用图卢克:)请接受答案,如果它适合你。不同之处在于使用图形操作(展开)而不是数千个索引查找。 –

1

在您的个人资料(NodeByQueryIndex)索引的查询。

你可以定义你想要哪个索引在查询中使用:

MATCH (n:Swedish) 
USING INDEX n:Swedish(surname) 
WHERE n.surname = 'Taylor' 
RETURN n 

http://neo4j.com/docs/stable/query-using.html

+0

我们正在使用遗留指标。 dba只是放在标签中,我会用带有新标签的节点的USING子句重试。 –

1

我们的解决方案是创建标签(lCompany),并添加对Company.id较新的索引类型列(CREATE INDEX ON:lCompany(id))。

查询,然后调整,以使用新的索引:

OPTIONAL MATCH 
    (pfComp:lCompany)<-[c:CHILD_OF*]-(cfComp:lCompany) 
WHERE pfComp.id = 2403226 
WITH 
    collect(cfComp.id) as cfCompIds 
    , pfComp 
OPTIONAL MATCH 
     (ptComp:lCompany)<-[c2:CHILD_OF*]-(ctComp:lCompany) 
WHERE ptComp.id = 1946633 
WITH cfCompIds, 
     collect(ctComp.id) AS ctCompIds, 
     pfComp, ptComp 
MATCH 
     (fComp:lCompany) -[fR:PARTICIPATES_IN]-> cdeals <-[tR:PARTICIPATES_IN]-(tComp:lCompany) 
USING INDEX fComp:lCompany(id) //tComp:lCompany(id) 
WHERE 
       ( 
        fComp.id in (cfCompIds + [2403226]) 
       ) 
       and 
       (
        tComp.id in (ctCompIds + [1946633]) 
       ) 
RETURN fComp, tComp, cdeals 

有可能是可以做到的futher优化,但是这是就我们已经走了这么远。

探查结果现在是:

暗号版本:2.2 CYPHER,规划师:COST。 134151总分贝命中1498毫秒。

这是好办法后的新轮廓:

enter image description here