【问题标题】:ndb.OR makes query costs morendb.OR 使查询成本更高
【发布时间】:2014-04-27 13:15:15
【问题描述】:

使用 AppEngine appstats 我分析了我的查询,并注意到尽管文档说查询需要读取一次,但使用 ndb.OR(或扩展为 OR 的 .IN)的查询需要 n 次读取(n 等于 OR 子句的数量)。

例如:

votes = (Vote.query(ndb.OR(Vote.object == keys[0], Vote.object == keys[1]))
     .filter(Vote.user_id == user_id)
     .fetch(keys_only=True))

此查询需要 2 次读取(匹配 0 个实体)。如果我将 ndb.OR 替换为 Vote.object.IN,则读取次数等于我传递给读取的数组的长度。

这种行为有点与文档相矛盾。

我想知道其他人是否也遇到过同样的情况,这是否是 AE、文档或我的理解中的错误。

谢谢。

【问题讨论】:

  • 你的理解有问题。查询的成本是针对基本查询的。阅读它如何执行 OR 和 IN,您会看到它创建多个查询然后合并数据,因此需要多个查询成本。
  • 谢谢。我实际上试图找到提到类似这样的东西,但找不到任何东西。
  • 它在文档中并不是特别明确,但是如果您阅读 ndb 查询文档,它就在那里(有点;-) 再读一次 developers.google.com/appengine/docs/python/ndb/queries

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


【解决方案1】:

ndb 的查询文档不是特别明确,但本段是您的最佳答案

除了原生运算符之外,API 还支持 != 运算符, 使用布尔 OR 运算和 IN 组合过滤器组 操作,测试与可能值列表之一的相等性 (如 Python 的 'in' 运算符)。这些操作不会 1:1 映射到 Datastore 的原生操作;因此它们有点古怪和缓慢, 相对地。它们是使用结果的内存合并实现的 流。请注意,p != v 被实现为“p v”。 (这个 对重复属性很重要。)

在此文档中https://developers.google.com/appengine/docs/python/ndb/queries

【讨论】:

  • 是的...我认为这是文档中的错误,而不是我的理解:)。我希望文档能够清楚地说明如此重要的事情。
  • 顺便说一句,考虑到这一点,如果我只想检查实体是否存在(假设我有一些查询标准和可能的键),有没有办法在不支付每张支票的情况下做到这一点?我使用了 get_multi() ,但这也需要读取不存在的实体,并且查询方法需要 IN 操作。我想知道是否还有其他方法...
  • 如果你有钥匙,最快的将是 get_multi,至于你的阅读次数,我会测试/分析替代方案。另一种是投影查询,它只返回索引中的值,因此如果满足您的要求,则不需要二次提取。
  • get_multi 是每个键的一个成本,无论它是否存在。每个潜在项目的查询将至少花费一个成本(由于您的解释)。所以我认为 get_multi 更好,除非我错过了什么。
猜你喜欢
  • 2021-11-14
  • 1970-01-01
  • 2015-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多