【问题标题】:improve NDB query performance提高 NDB 查询性能
【发布时间】:2013-02-13 19:48:18
【问题描述】:

我正在寻求建议,如何在速度方面提高这一点:

我的数据模型:

class Events(ndb.Model):
    eventid = ndb.StringProperty(required=True)
    participants = ndb.StringProperty(repeated=True)

我尝试获取数据的方式:

def GetEventDataNotCached(eventslist):
    futures = []
    for eventid in eventslist:
        if eventid is not None:
            ke = database.Events.query(database.Events.eventid == eventid)
            future = ke.get_async(keys_only = True)
            futures.append(future)

    eventskeys = []
    for future in futures:
        eventkey = future.get_result()  
        eventskeys.append(eventkey)

    data = ndb.get_multi(eventskeys)

所以我获得了异步密钥,而不是将密钥传递给“get_multi”——还有其他方法可以加快速度吗,因为我对性能仍然不满意。

在重复属性中最多可以有几百个字符串。 事件模型中有几个 10.000 行。 在 eventslist 中只有几十个我想要获取的 eventid。

【问题讨论】:

  • 我不确定这是否会使性能更好或更差,但也许您可以创建一个参与者实体。 Particpants.query(事件列表中的事件ID)

标签: python google-app-engine optimization app-engine-ndb


【解决方案1】:

我发现长列表(即大的repeated=True 属性)的协议缓冲区的反序列化开销非常小。

您在 appstats 中查看过这个吗?您是否看到在您的get_multi() 之后没有执行 RPC 的空白处很大?这就是反序列化开销。

我发现解决这个问题的唯一方法是删除长列表并在单独的模型中管理它们(即完全避免长重复的属性列表),但当然,这可能不适合您使用案例。

所以最大的问题是:当您获得事件列表时,您真的需要所有参与者,还是可以以某种方式推迟查找?例如,同步获取所有事件可能更便宜/更快,然后为每个事件(来自不同模型)的参与者启动异步获取并在内存中组合 - 也许您只需要 25 个最近注册的参与者或其他东西因此可以限制您的子查询的成本?

【讨论】:

    【解决方案2】:

    在简单性和执行速度方面而非成本方面的改进可能是:

    data = database.Events.query(database.Events.eventid.IN(eventslist)).fetch(100)
    

    下一步是将 eventid 作为 key 中的 id,创建方式类似于

    event = Event(id=eventid, ...)
    

    在这种情况下你会这样做

    data = ndb. get_multi(ndb.Key(Event, eventid) for eventid in eventlist)
    

    哪个更快,len(eventlist)*6 便宜。

    【讨论】:

      猜你喜欢
      • 2013-08-03
      • 2021-08-03
      • 2013-02-17
      • 2021-12-15
      • 2014-04-09
      • 2013-01-16
      • 2013-09-26
      • 2011-12-03
      相关资源
      最近更新 更多