3

我得到了以下情况

class M(db.Model):

    a = db.ReferenceProperty(A)

    x = db.ReferenceProperty(X)
    y = db.ReferenceProperty(Y)
    z = db.ReferenceProperty(Z)

    items = db.StringListProperty()

    date = db.DateTimeProperty()

我想进行过滤(a),(x,y或z)和(项目)的查询,按日期排序,即

mm = M.all().filter('a =', a1).filter('x =', x1).filter('items =', i).order('-date')

例如,永远不会有同时对 x 和 y 进行过滤的查询。

所以,我的问题是:

1) 我应该创建多少(以及哪些)索引?

2) 我可以在项目上添加多少“字符串”?(我想添加数千个)

3) 如果有 1000 个项目,我将在单个“M”上有多少条索引记录?

我还不太了解这个索引的东西,并且正在杀死我。您的帮助将不胜感激:)

4

3 回答 3

2

本文很好地解释了索引/爆炸索引,它实际上适合您的示例:https ://developers.google.com/appengine/docs/python/datastore/queries#Big_Entities_and_Exploding_Indexes

您最大的问题是您可能会遇到每个实体 5000 个索引以及数千个项目的限制。如果为 a, x, items (1000 items), date 取索引:|a| |x| |项目|*|日期| == 1*1*1000*1 == 1000。

如果项目中有 5001 个条目,则 put() 将失败并出现相应的异常。

从您提供的示例中,您是否过滤 x、y 或其他任何内容似乎都无关紧要,因为该属性只有 1 个,因此您不会遇到爆炸索引的机会。1*1 == 1。

现在,如果你有两个列表属性,你会想要确保它们被单独索引,否则你会得到一个爆炸索引。例如,如果您有 2 个列表属性,每个属性包含 100 个项目,则会产生 100*100 个索引,除非您拆分它们,否则只会产生 200 个(假设所有其他属性都是非列表)。

于 2012-05-13T18:12:42.127 回答
1
  1. 对于您给出的标准,您只需要创建三个复合索引:a,x,items,-date, a,y,items,-date, a,z,items,-date. 请注意,列表属性会为列表中的每个属性创建一个索引条目。

  2. 每个实体的索引条目总数限制为5000 个。如果您只有三个复合索引,则它是 5000/3 = 1666(单个列表属性的上限为 1000)。

  3. 仅在三个复合索引的情况下,3*1000 = 3000。

注意:以上假设您没有每个属性的内置索引(= 属性另存为未索引)。否则,您需要考虑 2N 的内置索引,其中 N 是单个属性的数量(2 代表 asc、desc)。在您的情况下,这将是 2*(5 + no_items),因为items它是一个列表属性,并且每个条目都会创建一个索引条目。

于 2012-05-13T19:12:49.987 回答
1

另请参阅https://developers.google.com/appengine/articles/indexselection,其中描述了 App Engine(相对较新)改进的查询计划功能。基本上,您可以将所需的索引条目数减少到:(过滤器数 + 1)*(订单数)。
不过,正如文章所讨论的,您可能仍然使用复合索引可能是有原因的——本质上,存在时间/空间权衡。

于 2012-05-14T01:44:27.053 回答