【问题标题】:How to quickly retrieve a number of rows from data store?如何从数据存储中快速检索多行?
【发布时间】:2016-04-19 18:06:18
【问题描述】:

在我正在处理的 Python GAE 应用程序中,我们需要从存储中检索 n 行,并且遇到 n > 100 的性能问题。我们预计 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要花7s。
  • 尝试使用任何合理的batch_size 强制fetch() 会进一步降低性能。我尝试了从 1 到 1000 的值。
  • 执行keys_only 可以提高一个数量级。
  • 手动执行查询 (through ndb.Query),然后只取出一个字段会带来小幅改进,大约是 1.2。
  • 执行fetch_async(n) 并等待提供完全相同的性能。
  • 将作业拆分为 p 部分,然后执行 fetch_async(n/p, offset=...),然后等待并加入所有期货 - 最好的性能相同,最坏的情况 - 性能更差。
  • fetch_page()类似的故事

我也试过用db代替ndb,结果几乎一样。所以,现在我不知道该怎么办?有没有办法让n 的性能达到 10000 的一半?即使将我的实体简化为单个字段,性能也太差了。我预计整个未压缩的有效载荷大约为 1 mb。在一分钟内下载 1mb 显然是不可接受的。

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

【问题讨论】:

  • 您在此请求的日志中看到了什么?
  • 获取行后你想做什么?

标签: performance google-app-engine


【解决方案1】:

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

【讨论】:

  • 获得大量查询对性能有好处,但我正在寻找一种通用解决方案,可以提高获得 n~10000 行的性能。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 2020-02-28
    • 1970-01-01
    相关资源
    最近更新 更多