Google App Engine请求在count()函数上超时

时间:2014-01-30 07:52:22

标签: python google-app-engine

我使用count()函数来计算查询返回的结果数。问题是计数花费的时间太长,请求超时。有什么方法可以让计数快速响应或者替换count()?

query = MyModel.query().filter(MyModel.name.IN(['john', 'sara', 'alex']))
search_count = query.count()

如果我删除了计数行,只返回结果只需几秒钟。

2 个答案:

答案 0 :(得分:4)

不幸的是,数量不会扩大。不使用游标,您只能计算1000个项目。其次,如果您想要计数仅执行密钥查询(从数据存储区中提取较少的数据)。

对于大量实体而言,实际上要保持计数相对最新,您需要使用任务并且每隔一段时间运行一次,(或者每次添加/修改数据时触发任务以进行调度)很少见,并把价值存放在某些地方。

或者想一想为什么你真的需要计数;-)以及它的准确程度。

答案 1 :(得分:0)

  1. 如果你需要count(),你应该使用Tim Hoffman已经建议的keys_only选项。这应该可以节省您足够的时间来计算小的查询结果。
  2. 请注意,count()实际上会在整个查询中运行,直到索引中的最后一个匹配为止。这意味着,如果您的查询与巨大索引中的数百万项匹配,即使使用keys_only选项,您也会看到糟糕的请求时间和超时。
  3. 从可用性的角度来看,用户不太可能想要大规模的准确数字。通常,用户甚至不会浏览数十页甚至数百页。

    具有阈值精度的计数器

    考虑使用仅精确到达下限的计数器,例如“找到41个项目”,超出该限制使用通用显示,例如“找到1000件以上的物品”。这就是GMail中的文本搜索显示匹配数量的方式。

    预先计算的计数器

    在Google搜索中输入“spaghetti”这样的通用术语,您会看到一些非常高的数字,例如: “发现了530万份文件”。然后尝试获取页码1,000或匹配数字1,000,000。它不会起作用。而且这个数字也是不准确的。为了提前计算匹配数,您可以编写任务/ cron作业(可能使用map-reduce),它将异步计算计数器。但是,即使在业务用例中,单个搜索查询的计数器(例如在您的示例中)也不需要对大数字进行准确,因为当用户完成结果时,计数​​器很可能会发生显着变化。

    分片计数器

    如果您需要一个准确的计数器,例如数据存储区中所有销售订单的数量,而不是单个查询,您可以编写一个计数器,并在每个创建或删除的新销售订单中增加/减少它。数据存储。根据您对实体组进行建模的方式,此类计数器可能会在大量写入中达到当前数据存储限制(每个实体组每秒写入1次,实际上可能为3到4次)。请参阅文章Sharding counters,其中介绍了如何构建可扩展的计数器。

    使用Search API

    您可以在Google App Engine中使用全文搜索服务。使用要搜索的字段定义索引(例如“客户”)。每当更新数据存储区中的客户实体时,将其更新的副本作为文档放入搜索索引中。根据我的经验,Search API可以更好地扩展到大型索引中的复杂搜索。它还会向您显示一个计数器,并为您的用户提供全文搜索功能。