neo4j - Streamsets:Neo4j 查询非常慢
问题描述
我正在使用 Streamsets 管道从远程上传 .csv 文件的活动文件目录中读取数据,并将这些数据放入 neo4j 数据库中。我使用的步骤是-
- 为 .csv 中的每一行创建一个观察节点
- 创建 csv 节点并在 csv 和记录之间创建关系
- 将从 csv 节点获取的时间戳更新到 burn_in_test 节点,如果它是最新的,则已经从不同的管道在图形数据库中创建
- 从 csv 创建关系以进行测试
- 根据最新时间戳删除过时的关系
现在我正在使用 jdbc 查询执行所有这些操作,并且使用的密码查询是
MERGE (m:OBSERVATION{
SerialNumber: "${record:value('/SerialNumber')}",
Test_Stage: "${record:value('/Test_Stage')}",
CUR: "${record:value('/CUR')}",
VOLT: "${record:value('/VOLT')}",
Rel_Lot: "${record:value('/Rel_Lot')}",
TimestampINT: "${record:value('/TimestampINT')}",
Temp: "${record:value('/Temp')}",
LP: "${record:value('/LP')}",
MON: "${record:value('/MON')}"
})
MERGE (t:CSV{
SerialNumber: "${record:value('/SerialNumber')}",
Test_Stage: "${record:value('/Test_Stage')}",
TimestampINT: "${record:value('/TimestampINT')}"
})
WITH m
MATCH (t:CSV) where t.SerialNumber=m.SerialNumber and t.Test_Stage=m.Test_Stage and t.TimestampINT=m.TimestampINT MERGE (m)-[:PART_OF]->(t)
WITH t, t.TimestampINT AS TimestampINT
MATCH (rl:Burn_In_Test) where rl.SerialNumber=t.SerialNumber and rl.Test_Stage=t.Test_Stage and rl.TimestampINT<TimestampINT
SET rl.TimestampINT=TimestampINT
WITH t
MATCH (rl:Burn_In_Test) where rl.SerialNumber=t.SerialNumber and rl.Test_Stage=t.Test_Stage
MERGE (t)-[:POINTS_TO]->(rl)
WITH rl
MATCH (t:CSV)-[r:POINTS_TO]->(rl) WHERE t.TimestampINT<rl.TimestampINT
DELETE r
现在这个过程非常缓慢,10 条记录大约需要 15 分钟的时间。这可以进一步优化吗?
解决方案
使用时的最佳实践MERGE
是合并单个属性,然后使用SET
添加其他属性。
如果我假设序列号属性对于每个节点都是唯一的(可能不是),它看起来像:
MERGE (m:OBSERVATION{SerialNumber: "${record:value('/SerialNumber')}"})
SET m.Test_Stage = "${record:value('/Test_Stage')}",
m.CUR= "${record:value('/CUR')}",
m.VOLT= "${record:value('/VOLT')}",
m.Rel_Lot= "${record:value('/Rel_Lot')}",
m.TimestampINT = "${record:value('/TimestampINT')}",
m.Temp= "${record:value('/Temp')}",
m.LP= "${record:value('/LP')}",
m.MON= "${record:value('/MON')}"
MERGE (t:CSV{
SerialNumber: "${record:value('/SerialNumber')}"
})
SET t.Test_Stage = "${record:value('/Test_Stage')}",
t.TimestampINT = "${record:value('/TimestampINT')}"
WITH m
MATCH (t:CSV) where t.SerialNumber=m.SerialNumber and t.Test_Stage=m.Test_Stage and t.TimestampINT=m.TimestampINT MERGE (m)-[:PART_OF]->(t)
WITH t, t.TimestampINT AS TimestampINT
MATCH (rl:Burn_In_Test) where rl.SerialNumber=t.SerialNumber and rl.Test_Stage=t.Test_Stage and rl.TimestampINT<TimestampINT
SET rl.TimestampINT=TimestampINT
WITH t
MATCH (rl:Burn_In_Test) where rl.SerialNumber=t.SerialNumber and rl.Test_Stage=t.Test_Stage
MERGE (t)-[:POINTS_TO]->(rl)
WITH rl
MATCH (t:CSV)-[r:POINTS_TO]->(rl) WHERE t.TimestampINT<rl.TimestampINT
DELETE r
要补充的另一件事是,我可能会将其拆分为两个查询。第一个是导入部分,第二个是删除关系。尽可能添加唯一的约束和索引。
推荐阅读
- css - 有没有办法格式化 node-sass css 输出?
- python - 为什么 Python 3 发现这个 ISO8601 日期:“2019-04-05T16:55:26Z”无效?
- google-apps-script - 如何消除对 Google 表格中按钮的 Google 脚本代码的权限
- image - 如何将多张图片拼接成一张图片?
- javascript - 更改 url 结尾以反映当前月份的脚本 Ex 04/01/2019
- braintree - Braintree:搜索订阅交易
- r - R中的动画GIF在每个间隔中丢失3毫秒
- scala - 使用 play-ws 读取许多主体时内存不足
- angularjs - 编写自定义指令以在 AngularJS (TypeScript) 中向 ng-options 添加工具提示
- python-3.x - 芹菜中未处理的异常冻结了工人