删除ndb查询结果的最有效方法

时间:2014-12-22 21:00:31

标签: python google-app-engine google-cloud-datastore app-engine-ndb

这是我目前的方法:

def delete_up_to_10000(query):
    for i in range(10):
        keys = query.fetch(1000, keys_only=True, deadline=40, batch_size=1000)
        ndb.delete_multi(keys)

我的问题是,是否可以删除查询结果而无需实际获取密钥?应该不可能吗?

以下是我当前解决方案的一些决策点:

  • 我决定不要一次超过1000来减少内存使用量。
  • 我从各种CRON任务中每分钟调用一次这种方法。
  • 根据数据的年龄和数据类型,我对可以安全删除的数据进行了一些查询 - 我目前有数十亿个实体。
  • 我希望从现在开始几年,数据仍然会以比写入数据存储区更快的速度被清除 - 因此将删除速率设置为当前写入速率的100倍左右。

3 个答案:

答案 0 :(得分:2)

您需要获取密钥才能执行删除操作。你是想尝试大规模删除而只是简单地将它传播出去吗?你应该研究一个mapper(即mapreduce)。它非常适合浏览大量数据存储条目和删除。您可以每天/每周运行一次地图作业,以控制数据。

答案 1 :(得分:1)

仅密钥查询不检索实体。它查看索引,但只查看您在查询中指定的索引。

"删除"另一方面,操作不仅必须删除实体本身,还必须删除该实体的每个索引的条目 - 无论它是属性索引还是复合索引。

因此,查询根本不具有同时执行删除操作所需的所有信息。假设"删除你找到的东西"操作只是"找到密钥列表的简写,然后使用这些密钥更新​​所有索引并删除实体本身"。"它可能会消除一些开销,但代价是更复杂。

答案 2 :(得分:0)

这是我现在的解决方案:

def _delete_from_query(query, limit, batch_size=2000):
    delete_count = 0
    next_curs = None
    while True:
        lim = min(batch_size, limit - delete_count)
        keys, next_curs, more = query.fetch_page(
            lim, start_cursor=next_curs, deadline=40, batch_size=lim, keys_only=True
        )
        ndb.delete_multi(keys)
        delete_count += len(keys)
        if not keys or not more or delete_count == limit:
            break
    return delete_count