2

我正在使用 paython-arango 和 aql 查询对多个项目(大约 20 - 30k)的 UPSERT 语句进行试验。总的来说,无论如何,与 NodeJS 相比,这种方法在 python 中似乎要慢得多,但我尝试了两种不同的方法,令人惊讶的是,我认为它的速度要慢得多,我试图理解为什么。

我最初的方法是用这样的语句单独更新每个项目:

        aql = "UPSERT {_key: '" + data["_key"] + "'}"
        aql += " INSERT " + doc
        aql += " UPDATE " + doc
        aql += " IN " + col_name
        
        self.db.aql.execute(aql)

正如我之前所说,这比 NodeJS 中的类似 NodeJS 脚本要慢,这可能是因为 NodeJS 是异步工作的。总共大约 45 秒 für 27k 条目(2.4 MB csv-dump)。这么少的数据花了很多时间。

然后我想,一个一个可能是问题所在,最好将每个查询的多个项目发送到数据库,如下所示:

        aql = "FOR itm IN " + json.dumps(items)
        aql += " UPSERT {_key: itm._key}"
        aql += " INSERT itm"
        aql += " UPDATE itm"
        aql += " IN " + col_name

但实际上,情况更糟。可能需要 5 分钟,ArangoDB-Backend 的速度非常慢,并且在短时间内甚至无法访问。

我很好奇:为什么一个单独的(好吧,我使用了 2、10、50、100 个项目但没有效果的批次)aql 语句与 FOR 比 27k 单独请求慢得多?我预计不是这样。有没有更好的方法一次执行多个 UPSERT(使用 Python)?

它是具有 2 个内核和 16 GB RAM 的 Windows 系统。阅读成绩不错,但写作...

4

1 回答 1

0

UPSERT 执行嵌套查询以查找匹配的文档。但是,这并不能解释为什么单个查询的性能比多个查询差得多,除非您当然异步/并行执行这些查询。我将不得不更详细地研究这一点。

但是,由于您使用_key来标识您的文档,并且您的INSERTandUPDATE语句看起来相同,因此您最好使用overwriteModeforINSERT来代替(请参阅https://www.arangodb.com/docs/stable/aql/operations-insert.html#查询选项):

        aql = "FOR itm IN " + json.dumps(items)
        aql += " INSERT itm"
        aql += " IN " + col_name
        aql += " OPTIONS { overwriteMode: 'update' }"

但是在处理大量文档时,您应该考虑改用批量文档创建(https://www.arangodb.com/docs/stable/http/document-working-with-documents.html#create-multiple-documents)这也支持overwriteMode. 但是,我不知道python-arango驱动是否支持这些功能。

于 2021-06-08T12:33:50.250 回答