如何从数据存储中快速检索多个行?

时间:2016-04-19 18:06:19

标签: performance google-app-engine

在我正在处理的Python GAE应用程序中,我们需要从存储中检索n行,并且我们遇到n>的性能问题。我们希望在大多数情况下n小于10000。

因此,让我们考虑一个简单的模型:

class MyEntity(ndb.Model):
    field1 = nbd.StringProperty()
    field2 = ndb.StringProperty()
    #...
    fieldm = ndb.StringProperty()
    # m is quite large, maybe ~ 30. Stored strings are short - in the order of 30 characters or less

我已经使用一些数据填充了数据存储,并且使用普通fetch()获得了非常糟糕的性能。我已经删除了所有过滤器,并且只是尝试获取许多实体似乎会获得非常糟糕的性能(与我期望的任何常见SQL部署相比。我知道我们不应该这样做。将GAE与SQL进行比较,但只是将平行排成一行 - 我希望它的性能更高,而不是更低。以下是我尝试过的内容:

  • 最简单的方法MyEntity.all().fetch(n)。这与n呈线性关系,这是预期的。虽然我没想到n = 1000需要7分。
  • 尝试强制fetch()任何合理的batch_size进一步降低性能。我尝试过的值介于1到1000之间。
  • keys_only可以提高数量级。
  • 手动执行查询(through ndb.Query),只取出一个字段可以得到一个很小的改进,大约为1.2。
  • 执行fetch_async(n)并等待提供完全相同的效果。
  • 将作业拆分为p部分,然后执行fetch_async(n/p, offset=...),然后等待并加入所有期货 - 最好提供相同的性能,最糟糕的是 - 性能要差得多。
  • fetch_page()
  • 类似的故事

我还尝试使用db代替ndb,结果几乎相同。那么,现在我不知道该怎么办?有没有办法让10000 {10000}的n获得一半不错的表现?即使将我的实体简化为单个字段,性能也太差。我希望未压缩的整个有效载荷大约为1 mb。在一分钟内下载1mb显然是不可接受的。

我现在看到这个问题,但是对于性能测试,我使用的是远程api。我的问题类似于关于SO的这个问题:Best practice to query large number of ndb entities from datastore。他们似乎没有找到解决方案,但4年前有人问过,也许现在有一个。

2 个答案:

答案 0 :(得分:1)

如果您只需要模型的字段子集,请查看Projection Queries

答案 1 :(得分:1)

您可以获得更好的性能,具体取决于您需要对检索到的数据执行的操作。例如,使用您提到的_async documentation here。您可以检索数据的子集,比如前100,然后在处理第一个数据批处理时,在100个记录的下一个子集上调用_async,因为_async是非阻塞的。在进行结束时,使用.get_result()检索第二批结果并开始处理其数据,同时使用_async ...等调用第三批。