Estou executando a mesma consulta no Neo4j e notando que o tempo de execução varia significativamente. Por exemplo, a consulta pode ser executada em 5-6 segundos, enquanto em outro momento leva 2-3 minutos, mesmo que os dados permaneçam inalterados.
: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;
aqui estão alguns dados do meu arquivo de configuração que foram descomentários, se necessário
server.memory.heap.initial_size=8G
server.memory.heap.max_size=16G
dbms.memory.transaction.total.max=32G
EXPLIQUE minha consulta
Por que a execução da mesma consulta no Neo4j pode levar quantidades de tempo diferentes? Quais fatores podem influenciar isso e como posso otimizar seu desempenho?
A causa da lentidão é que você não tem um índice em
:Person(person_id)
, o que explicaria por que as primeiras execuções (com poucos dados) são executadas rapidamente, mas se tornam cada vez mais caras à medida que os dados são carregados ou em um CSV maior para ingestão.Sem um índice, o custo da parte MATCH do MERGE (já que um MERGE é como um MATCH e então um CREATE, se nenhuma correspondência for encontrada) aumenta linearmente com o número de nós :Person no gráfico. Com um índice, ainda há um custo crescente, mas é uma complexidade log(n) devido ao uso do índice, então deve permanecer eficiente.
Adicione o índice, confirme se ele é usado no plano EXPLAIN (você deve ver um operador NodeIndexSeek e nenhum operador NodeByLabelScan) e teste novamente.