优化neo4j cypher导入查询
Optimize neo4j cypher import query
我使用 Neo4j.Driver.V1 在 C# 中创建了一个应用程序,该应用程序从 CSV 中读取并将其写入 neo4j 图形数据库。
我的 csv 有 1000 条记录。每条记录被分成 5 个节点,它们之间有关系。
整个过程耗时 1 分 11 秒(包括我构建查询背后的逻辑所需的 1 秒)。
考虑到他们将上传数百万条记录,这太多了。
这是我的查询:
MERGE
(accountd71d278a8eeb468f9e4517ac1e007fe5:Account
{
number: '952'
} )
ON CREATE
SET accountd71d278a8eeb468f9e4517ac1e007fe5 +=
{
number: '952',
balanceType: 2,
accountType: 2,
openDate: apoc.date.parse('7/9/2015', 'ms', 'm/d/YYYY')
}
MERGE (account13aa03cd1b6d449e88a3e5e5a22353da:Account
{
number: '198'
} )
ON CREATE
SET account13aa03cd1b6d449e88a3e5e5a22353da +=
{
number: '198'
}
MERGE (transactionba1459c4f7854157be237e7365497fcf:Transaction
{
number: '1'
} )
ON CREATE
SET transactionba1459c4f7854157be237e7365497fcf +=
{
number: '1',
amount: 3717.81,
type: 2,
date: apoc.date.parse('2016-05-27', 'ms', 'YYYY-mm-dd')
}
MERGE (bank3679799504f54bed9f079848be9c6eff:Bank
{
code: 'MMBC'
} )
ON CREATE
SET bank3679799504f54bed9f079848be9c6eff +=
{
code: 'MMBC',
country: 'Mongolia'
}
MERGE (bank522b6b6ed04d40bd9d87d4ecc36fbde2:Bank
{
code: 'VALL'
} )
ON CREATE
SET bank522b6b6ed04d40bd9d87d4ecc36fbde2 +=
{
code: 'VALL',
country: 'Mongolia'
}
MERGE (accountd71d278a8eeb468f9e4517ac1e007fe5)-[:credits]->(transactionba1459c4f7854157be237e7365497fcf)
MERGE (accountd71d278a8eeb468f9e4517ac1e007fe5)-[:residesWith]->(bank3679799504f54bed9f079848be9c6eff)
MERGE (transactionba1459c4f7854157be237e7365497fcf)-[:debits]->(account13aa03cd1b6d449e88a3e5e5a22353da)
MERGE (account13aa03cd1b6d449e88a3e5e5a22353da)-[:residesWith]->(bank522b6b6ed04d40bd9d87d4ecc36fbde2)
有什么可以减少查询时间的想法吗?
在提供任何想法之前,这是我已经尝试过的:
- 删除带有 GUID 的长名称
- 删除对 apoc 日期解析的使用
- 考虑使用从 csv 导入的内置功能,但数据库在另一台服务器上
- 组合多个记录查询(结果是 2 个同时执行最好)
- 创建约束
提前致谢!
K
这是优化流程的要点列表:
- 使用查询参数:您所有的查询数据都应该是一个参数。如果你这样做,Neo4j 将不会在每次查询规划器时重新计算
- 批量查询:我认为您对 CSV 的每一行都进行了一次交易。尝试对您的查询进行 bacth(1000 行的一个事务应该没问题,但如果您的 CSV 会增长,您确实需要更多事务)
- 创建 每个 node/relationship 创建一个查询 而不是做一个大查询,并且对于关系使用
MATCH MATCH MERGE
模式(你有约束,所以它会很快)
我使用 Neo4j.Driver.V1 在 C# 中创建了一个应用程序,该应用程序从 CSV 中读取并将其写入 neo4j 图形数据库。
我的 csv 有 1000 条记录。每条记录被分成 5 个节点,它们之间有关系。
整个过程耗时 1 分 11 秒(包括我构建查询背后的逻辑所需的 1 秒)。
考虑到他们将上传数百万条记录,这太多了。
这是我的查询:
MERGE
(accountd71d278a8eeb468f9e4517ac1e007fe5:Account
{
number: '952'
} )
ON CREATE
SET accountd71d278a8eeb468f9e4517ac1e007fe5 +=
{
number: '952',
balanceType: 2,
accountType: 2,
openDate: apoc.date.parse('7/9/2015', 'ms', 'm/d/YYYY')
}
MERGE (account13aa03cd1b6d449e88a3e5e5a22353da:Account
{
number: '198'
} )
ON CREATE
SET account13aa03cd1b6d449e88a3e5e5a22353da +=
{
number: '198'
}
MERGE (transactionba1459c4f7854157be237e7365497fcf:Transaction
{
number: '1'
} )
ON CREATE
SET transactionba1459c4f7854157be237e7365497fcf +=
{
number: '1',
amount: 3717.81,
type: 2,
date: apoc.date.parse('2016-05-27', 'ms', 'YYYY-mm-dd')
}
MERGE (bank3679799504f54bed9f079848be9c6eff:Bank
{
code: 'MMBC'
} )
ON CREATE
SET bank3679799504f54bed9f079848be9c6eff +=
{
code: 'MMBC',
country: 'Mongolia'
}
MERGE (bank522b6b6ed04d40bd9d87d4ecc36fbde2:Bank
{
code: 'VALL'
} )
ON CREATE
SET bank522b6b6ed04d40bd9d87d4ecc36fbde2 +=
{
code: 'VALL',
country: 'Mongolia'
}
MERGE (accountd71d278a8eeb468f9e4517ac1e007fe5)-[:credits]->(transactionba1459c4f7854157be237e7365497fcf)
MERGE (accountd71d278a8eeb468f9e4517ac1e007fe5)-[:residesWith]->(bank3679799504f54bed9f079848be9c6eff)
MERGE (transactionba1459c4f7854157be237e7365497fcf)-[:debits]->(account13aa03cd1b6d449e88a3e5e5a22353da)
MERGE (account13aa03cd1b6d449e88a3e5e5a22353da)-[:residesWith]->(bank522b6b6ed04d40bd9d87d4ecc36fbde2)
有什么可以减少查询时间的想法吗?
在提供任何想法之前,这是我已经尝试过的:
- 删除带有 GUID 的长名称
- 删除对 apoc 日期解析的使用
- 考虑使用从 csv 导入的内置功能,但数据库在另一台服务器上
- 组合多个记录查询(结果是 2 个同时执行最好)
- 创建约束
提前致谢!
K
这是优化流程的要点列表:
- 使用查询参数:您所有的查询数据都应该是一个参数。如果你这样做,Neo4j 将不会在每次查询规划器时重新计算
- 批量查询:我认为您对 CSV 的每一行都进行了一次交易。尝试对您的查询进行 bacth(1000 行的一个事务应该没问题,但如果您的 CSV 会增长,您确实需要更多事务)
- 创建 每个 node/relationship 创建一个查询 而不是做一个大查询,并且对于关系使用
MATCH MATCH MERGE
模式(你有约束,所以它会很快)