python - 为什么 allshortestpath 这么慢?
问题描述
我用 python 和 neo4j 库创建了一些图形数据库。图有 50k 个节点和 100k 个关系。
如何创建节点:
CREATE (user:user {task_id: %s, id: %s, root: 1, private: 0})
如何建立关系:
MATCH (root_user), (friend_user) WHERE root_user.id = %s
AND root_user.task_id = %s
AND friend_user.id = %s
AND friend_user.task_id = %s
CREATE (root_user)-[r: FRIEND_OF]->(friend_user) RETURN root_user, friend_user
我如何搜索节点之间的所有路径:
MATCH (start_user:user {id: %s, task_id: %s}),
(end_user:user {id: %s, task_id: %s}),
path = allShortestPaths((start_user)-[*..3]-(end_user)) RETURN path
Soo 非常慢,在 50k 图表上大约需要 30-60 分钟。我不明白为什么。我尝试像这样创建索引:
CREATE INDEX ON :user(id, task_id)
但它没有帮助。你能帮助我吗?谢谢。
解决方案
你永远不应该生成一个长的 Cypher 查询,其中包含本质上相同的 Cypher 代码的 N 个细微变化。这非常慢并且占用大量内存。
相反,您应该将参数传递给更简单的 Cypher 查询。
例如,在创建节点时,您可以将data
参数传递给以下 Cypher 代码:
UNWIND $data AS d
CREATE (user:user {task_id: d.taskId, id: d.id, root: 1, private: 0})
您传递的data
参数值将是一个映射列表,每个映射将包含一个taskId
和id
。该UNWIND
子句将data
列表“展开”为单独的d
地图。这会快得多。
需要对您的关系创建代码执行类似的操作。
此外,为了使用您的任何:user
索引,您的MATCH
子句必须:user
在相关节点模式中指定标签。否则,您要求 Cypher 扫描所有节点,而不考虑标签,并且这种处理将无法利用索引。例如,相关查询应以:
MATCH (root_user:user), (friend_user:user)
...
推荐阅读
- php - 为什么这个 file_get_contents() 有时有效,有时无效?
- android - Android - 在 ImageView 周围绘制边框
- swift - 如何从 NSObject 数组中过滤项目
- c# - 如何在 SQL 的存储过程中将参数传递给 bcp
- ibm-cloud-infrastructure - { 错误:'服务不存在',代码:'SoftLayer_Exception_Public',
- encryption - FFMPEG 是否支持 Apple Fairplay DRM 所需的 AES128 样本加密?
- dart - 基于未经授权的 API 响应注销
- node.js - Zip文件上传超过1 GB不适用于nodejs?
- javascript - 获取数组中的所有元素?
- android - 如何为不同的通知设置不同的声音?