我应该使用 Neo4j 的导入工具还是加载命令来插入几百万行?
Should I use Neo4j's Import Tool or Load Command to Insert Several Million Rows?
我有几个 CSV 文件,大小在 25-100 MB 之间。我创建了约束,创建了索引,正在使用定期提交,并增加了 neo4j-wrapper.conf 和 neo4j.properties 中分配的内存。
neo4j.properties:
neostore.nodestore.db.mapped_memory=50M
neostore.relationshipstore.db.mapped_memory=500M
neostore.propertystore.db.mapped_memory=100M
neostore.propertystore.db.strings.mapped_memory=100M
neostore.propertystore.db.arrays.mapped_memory=0M
neo4j-wrapper.conf 变化:
wrapper.java.initmemory=5000
wrapper.java.maxmemory=5000
但是我的加载仍然需要很长时间,我正在考虑使用最近发布的导入工具(http://neo4j.com/docs/milestone/import-tool.html)。在我切换到它之前,我想知道我是否可以做任何其他事情来提高导入速度。
我首先创建几个约束以确保我使用的 ID 是唯一的:
CREATE CONSTRAINT ON (Country) ASSERT c.Name IS UNIQUE;
//and constraints for other name identifiers as well..
然后我使用定期提交...
USING PERIODIC COMMIT 10000
然后我在忽略几个字段的 CSV 中加载
LOAD CSV WITH HEADERS FROM "file:/path/to/file/MyFile.csv" as line
WITH line
WHERE line.CountryName IS NOT NULL AND line.CityName IS NOT NULL AND line.NeighborhoodName IS NOT NULL
然后我根据我的数据创建必要的节点。
WITH line
MERGE(country:Country {name : line.CountryName})
MERGE(city:City {name : line.CityName})
MERGE(neighborhood:Neighborhood {
name : line.NeighborhoodName,
size : toInt(line.NeighborhoodSize),
nickname : coalesce(line.NeighborhoodNN, ""),
... 50 other features
})
MERGE (city)-[:IN]->(Country)
CREATE (neighborhood)-[:IN]->(city)
//Note that each neighborhood only appears once
使用 CREATE UNIQUE 而不是将 MERGE 应用于任何 COUNTRY 引用是否有意义?这会加快速度吗?
一个约 250,000 行的 CSV 文件用了 12 多个小时才完成,而且速度似乎太慢了。我还能做些什么来加快速度?还是使用看起来很烦人的导入工具才有意义?
几件事。首先,我建议阅读 Mark Needham 的 "Avoiding the Eager" 博客 post:
http://www.markhneedham.com/blog/2014/10/23/neo4j-cypher-avoiding-the-eager/
基本上它说的是您应该在每个查询的开头添加一个 PROFILE
以查看它们是否使用 Eager
运算符。如果他们这样做确实会降低你的性能,你应该将你的查询拆分成单独的 MERGE
s
其次,您的社区 MERGE
包含很多属性,因此每次它都会在决定是否应该创建它之前尝试匹配这些属性中的每一个。我建议像这样:
MERGE (neighborhood:Neighborhood {name: line.NeighborhoodName})
ON CREATE SET
neighborhood.size = toInt(line.NeighborhoodSize),
neighborhood.nickname = coalesce(line.NeighborhoodNN, ""),
... 50 other features
})
我有几个 CSV 文件,大小在 25-100 MB 之间。我创建了约束,创建了索引,正在使用定期提交,并增加了 neo4j-wrapper.conf 和 neo4j.properties 中分配的内存。
neo4j.properties:
neostore.nodestore.db.mapped_memory=50M
neostore.relationshipstore.db.mapped_memory=500M
neostore.propertystore.db.mapped_memory=100M
neostore.propertystore.db.strings.mapped_memory=100M
neostore.propertystore.db.arrays.mapped_memory=0M
neo4j-wrapper.conf 变化:
wrapper.java.initmemory=5000
wrapper.java.maxmemory=5000
但是我的加载仍然需要很长时间,我正在考虑使用最近发布的导入工具(http://neo4j.com/docs/milestone/import-tool.html)。在我切换到它之前,我想知道我是否可以做任何其他事情来提高导入速度。
我首先创建几个约束以确保我使用的 ID 是唯一的:
CREATE CONSTRAINT ON (Country) ASSERT c.Name IS UNIQUE;
//and constraints for other name identifiers as well..
然后我使用定期提交...
USING PERIODIC COMMIT 10000
然后我在忽略几个字段的 CSV 中加载
LOAD CSV WITH HEADERS FROM "file:/path/to/file/MyFile.csv" as line
WITH line
WHERE line.CountryName IS NOT NULL AND line.CityName IS NOT NULL AND line.NeighborhoodName IS NOT NULL
然后我根据我的数据创建必要的节点。
WITH line
MERGE(country:Country {name : line.CountryName})
MERGE(city:City {name : line.CityName})
MERGE(neighborhood:Neighborhood {
name : line.NeighborhoodName,
size : toInt(line.NeighborhoodSize),
nickname : coalesce(line.NeighborhoodNN, ""),
... 50 other features
})
MERGE (city)-[:IN]->(Country)
CREATE (neighborhood)-[:IN]->(city)
//Note that each neighborhood only appears once
使用 CREATE UNIQUE 而不是将 MERGE 应用于任何 COUNTRY 引用是否有意义?这会加快速度吗?
一个约 250,000 行的 CSV 文件用了 12 多个小时才完成,而且速度似乎太慢了。我还能做些什么来加快速度?还是使用看起来很烦人的导入工具才有意义?
几件事。首先,我建议阅读 Mark Needham 的 "Avoiding the Eager" 博客 post:
http://www.markhneedham.com/blog/2014/10/23/neo4j-cypher-avoiding-the-eager/
基本上它说的是您应该在每个查询的开头添加一个 PROFILE
以查看它们是否使用 Eager
运算符。如果他们这样做确实会降低你的性能,你应该将你的查询拆分成单独的 MERGE
s
其次,您的社区 MERGE
包含很多属性,因此每次它都会在决定是否应该创建它之前尝试匹配这些属性中的每一个。我建议像这样:
MERGE (neighborhood:Neighborhood {name: line.NeighborhoodName})
ON CREATE SET
neighborhood.size = toInt(line.NeighborhoodSize),
neighborhood.nickname = coalesce(line.NeighborhoodNN, ""),
... 50 other features
})