我正在创建一个使用 ArangoDB 作为数据存储的 Node.js 应用程序。基本上,我拥有的数据结构是两张表,一张用于管理所谓instances
的entities
. 我要做的是:
- 对于我拥有
instances
的每一个,集合中都有一个文档。instance
- 每当我将实体添加到
entities
集合中时,我还想跟踪属于特定实例的实体。 - 因此,每个
instance
文档都有一个用于 的数组字段entities
,我将实体的 ID 推送到该数组中。
以下代码显示了一般大纲:
// Connect to ArangoDB.
db = new Database(...);
db.useBasicAuth(user, password);
// Use the database.
await db.createDatabase(database);
db.useDatabase(database);
// Create the instance collection.
instanceCollection = db.collection(`instances-${uuid()}`);
await instanceCollection.create();
// Create the entities collection.
entityCollection = db.collection(`entities-${uuid()}`);
await entityCollection.create();
// Setup an instance.
instance = {
id: uuid(),
entities: []
};
// Create the instance in the database.
await db.query(aql`
INSERT ${instance} INTO ${instanceCollection}
`);
// Add lots of entities.
for (let i = 0; i < scale; i++) {
// Setup an entity.
const entity = {
id: uuid()
};
// Update the instance.
instance.entities.push(entity);
// Insert the entity in the database.
await db.query(aql`
INSERT ${entity} INTO ${entityCollection}
`);
// Update the instance in the database.
await db.query(aql`
FOR i IN ${instanceCollection}
FILTER i.id == ${instance.id}
UPDATE i WITH ${instance} IN ${instanceCollection} OPTIONS { mergeObjects: false }
`);
}
现在的问题是,我添加的实体越多,这变得非常慢。它基本上呈指数增长,尽管我预计会线性增长:
Running benchmark 'add and update'
100 Entities: 348.80ms [+0.00%]
1000 Entities: 3113.55ms [-10.74%]
10000 Entities: 90180.18ms [+158.54%]
添加索引会产生效果,但不会改变整体问题的任何内容:
Running benchmark 'add and update with index'
100 Entities: 194.30ms [+0.00%]
1000 Entities: 2090.15ms [+7.57%]
10000 Entities: 89673.52ms [+361.52%]
问题可以追溯到UPDATE
语句。如果你把它排除在外,只使用数据库的INSERT
语句,事情就会线性扩展。因此,更新本身似乎有问题。但是,我不明白问题出在哪里。
这就是我想理解的:为什么UPDATE
语句会随着时间的推移而显着变慢?我用错了吗?这是 ArangoDB 中的一个已知问题吗?……?
我不感兴趣的是讨论这种方法: Please take is as given。让我们关注UPDATE
语句的性能。有任何想法吗?
更新
正如评论中所要求的,这里有一些关于系统设置的信息:
- ArangoDB 3.4.6、3.6.2.1 和 3.7.0-alpha.2(都在 Docker、macOS 和 Linux 上运行)
- 单服务器设置
- ArangoJS 6.14.0(我们在早期版本中也有这个,虽然我不能告诉确切的版本)