我在一台装有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文件中的每一行都匹配?
对此的任何想法都会受到赞赏。
答案 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))))));
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
已经消失了。