Google App Engine ndb.delete_multi() 的效率如何?

3 投票
2 回答
1328 浏览
提问于 2025-04-18 15:58

我正在处理一个清理数据库的任务,里面大约有10,000个实体。我计划把这个任务分成每次删除200个实体,使用ndb.delete_multi(),然后再递归调用自己,直到所有实体都被删除。

目前,我还没有实现递归,所以我可以手动运行几次代码,检查错误、配额使用情况等。代码如下:

entities = MyModel.query_all(ndb.Key('MyModel', '*defaultMyModel')).fetch(200)
key_list = ndb.put_multi(entities)
ndb.delete_multi(key_list)

这里的query_all()只是查询MyModel并返回所有内容。

我做了一些测试,通过注释掉一些内容并运行这个方法,发现前两行代码的写入量是预期的(大约200次)。

但是运行第三行ndb.delete_multi()时,竟然用了我每天50,000次写入配额的8%,也就是大约4000次写入——这比我预想的多了20倍。

我还确保key_list里只有200个键,并进行了记录。

有没有人知道为什么会消耗这么多写入?我是不是用错了这个方法?或者它就是需要大量内存?如果是这样,有没有更有效的方法来处理这个问题?

谢谢。

2 个回答

4

当你删除一个实体的时候,数据存储系统需要把这个实体和它在每个索引属性下的记录都删掉,还要处理每个自定义索引。无论你使用哪种删除方法,写入的次数都是一样的。

3

你的代码示例效率非常低。如果你要删除很多数据,那你需要把下面的操作分批进行。不过,你应该先用只获取键的查询来获取数据,然后再进行删除:

from google.appengine.ext import ndb

ndb.delete_multi(
    MyModel.query().fetch(keys_only=True)
)

关于写操作的数量(可以参考Andrei的回答),确保你的模型中只有需要被索引的字段“开启索引”。

撰写回答