我在 Neo4j 中运行相同的查询,并注意到执行时间差异很大。例如,查询可能在 5-6 秒内执行,而有时则需要 2-3 分钟,即使数据保持不变。
:param {
idsToExclude: []
};
:auto LOAD CSV WITH HEADERS FROM ('file:///PERSON_DATA.csv') AS row
WITH row
WHERE NOT row.`person_id` IN $idsToExclude AND NOT row.`person_id` IS NULL
CALL {
WITH row
MERGE (n: `Person` { `person_id`: row.`person_id` })
SET n.`person_id` = row.`person_id`
SET n.`name` = row.`name`
SET n.`age` = toInteger(row.`age`)
SET n.`email` = row.`email`
SET n.`address` = row.`address`
SET n.`creation_date` = datetime(row.`creation_date`)
SET n.`last_modified_date` = datetime(row.`last_modified_date`)
} IN TRANSACTIONS OF 5000 ROWS;
这是我的配置文件中的一些数据,如果需要的话,这些数据已被取消注释
server.memory.heap.initial_size=8G
server.memory.heap.max_size=16G
dbms.memory.transaction.total.max=32G
解释我的查询
为什么在 Neo4j 中执行相同的查询会花费不同的时间?哪些因素会影响这一点,以及如何优化其性能?
速度变慢的原因是您没有索引
:Person(person_id)
,这可以解释为什么早期运行(数据很少)执行速度很快,但是随着数据的加载或使用更大的 CSV 进行提取,成本会变得越来越高。如果没有索引,MERGE 的 MATCH 部分的成本(因为 MERGE 类似于 MATCH,如果没有找到匹配项,则类似于 CREATE)会随着图中 :Person 节点的数量线性增加。使用索引时,成本仍然会增加,但由于使用了索引,其复杂度为 log(n),因此应该保持高效。
添加索引,确认索引在 EXPLAIN 计划中使用(您应该看到 NodeIndexSeek 运算符而没有 NodeByLabelScan 运算符),然后再次测试。