Cypher MATCH查询速度

时间:2015-04-08 17:28:20

标签: neo4j cypher

我在一台装有12个处理器和64GB内存的Windows机器上安装了Neo4j。我没有更改Neo4j允许的任何内存设置。

我的数据库有3.8米节点,其中210,000个标记为地理标记,总共650,000个关系。我试图运行以下查询,我想知道这是否是一个真正密集的查询,可能需要一段时间。

Messages.csv是我的关系文件。已经创建了关系,但由于我无法弄清楚如何将关系创建与下面的距离生成相结合,我将加载并运行两次关系文件。

USING PERIODIC COMMIT 15000
LOAD CSV WITH HEADERS FROM "file:d:/messages.csv" AS line
MATCH (a:Geotagged { username: line.sender }) - [r:MSGED] -> (b:Geotagged { username: line.recipient })
SET r.Distance = (2 * 6371 * asin(sqrt(haversin(radians(toFloat(b.statusLat) - toFloat(a.statusLat))) + cos(radians(toFloat(b.statusLat))) * cos(radians(toFloat(a.statusLat))) * haversin(radians(toFloat(b.statusLon) - toFloat(a.statusLon))))));

初始关系生成大约需要3-5分钟。我让上面运行了一个多小时,但仍然没有完成。我在同一个初始数据库上运行了一个类似的算法(尽管它有更多的三次调用),让它运行超过18个小时但仍然没有完成。

我的问题:这是一个非常密集的查询吗?我没有给它足够的时间吗?更重要的是,有没有一种方法可以优化它?

我尝试添加"哪里没有(r.Distance)"排除算法已设置距离的节点对,但我不确定MATCH是一次性匹配还是CSV文件中的每一行都匹配?

对此的任何想法都会受到赞赏。

2 个答案:

答案 0 :(得分:2)

我开始调试的一种方法是使用WITH

对其进行限制
USING PERIODIC COMMIT 15000
LOAD CSV WITH HEADERS FROM "file:d:/messages.csv" AS line
WITH line LIMIT 100
MATCH (a:Geotagged { username: line.sender }) - [r:MSGED] -> (b:Geotagged { username: line.recipient })
SET r.Distance = (2 * 6371 * asin(sqrt(haversin(radians(toFloat(b.statusLat) - toFloat(a.statusLat))) + cos(radians(toFloat(b.statusLat))) * cos(radians(toFloat(a.statusLat))) * haversin(radians(toFloat(b.statusLon) - toFloat(a.statusLon))))));

通过这种方式,您可以更改LIMIT数字,以了解性能随着限制的增加而降低。

此外,username标签的Geotagged属性索引是?如果不是,它肯定应该是这样的:

CREATE INDEX ON :Geotagged(username)

如果它是唯一的,并且您希望数据库强制执行:

CREATE CONSTRAINT ON (g:Geotagged) ASSERT g.username IS UNIQUE

答案 1 :(得分:2)

这是Brian回复的补充:

您的对帐单的查询计划显示EAGER,以验证运行

EXPLAIN explain LOAD CSV WITH HEADERS FROM "file:d:/messages.csv" AS line
WITH line LIMIT 100
MATCH (a:Geotagged { username: line.sender }) - [r:MSGED] -> (b:Geotagged { username: line.recipient })
SET r.Distance = (2 * 6371 *asin(sqrt(haversin(radians(toFloat(b.statusLat) - toFloat(a.statusLat))) + cos(radians(toFloat(b.statusLat))) * cos(radians(toFloat(a.statusLat))) * haversin(radians(toFloat(b.statusLon) - toFloat(a.statusLon))))));

query plan with eager

LOAD CSV中的渴望非常糟糕,请参阅这些博客文章原因:

按照Mark的建议并将MATCH/SET替换为MERGE ON MATCH SET,我们可以将其重构为:

explain LOAD CSV WITH HEADERS FROM "file:d:/messages.csv" AS line
WITH line LIMIT 100
MATCH (a:Geotagged { username: line.sender }), (b:Geotagged { username: line.recipient })
MERGE (a)-[r:MSGED]->(b)
ON MATCH SET r.Distance = (2 * 6371 * asin(sqrt(haversin(radians(toFloat(b.statusLat) - toFloat(a.statusLat))) + cos(radians(toFloat(b.statusLat))) * cos(radians(toFloat(a.statusLat))) * haversin(radians(toFloat(b.statusLon) - toFloat(a.statusLon))))));

eager已经消失了。 query plan without eager