关于appengine索引的3个问题

时间:2012-05-13 09:46:23

标签: python google-app-engine indexing

我遇到以下情况

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”上有多少个索引记录?

我还不太明白这个索引的东西,并且正在杀了我。非常感谢您的帮助:)

3 个答案:

答案 0 :(得分:2)

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

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

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

从您提供的示例中,无论您对x,y还是其他任何内容进行过滤都显得无关紧要,因为该属性中只有1个,因此您不会冒爆炸索引的可能性。 1 * 1 == 1。

现在,如果您有两个列表属性,则需要确保它们是单独索引的,否则您将获得爆炸索引。例如,如果你有2个列表属性与每个100个项目,这将产生100×100点的索引,除非你分割它们,然后这将导致只有200(假设所有其它性质是非列表)。

答案 1 :(得分:1)

  1. 根据您提供的标准,您只需要创建三个复合索引:a,x,items,-datea,y,items,-datea,z,items,-date。请注意,list属性为列表中的每个属性创建索引条目。

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

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

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

答案 2 :(得分:1)

另请参阅https://developers.google.com/appengine/articles/indexselection,其中介绍了App Engine(相对较新的)改进的查询规划功能。基本上,您可以减少所需的索引条目数量:(过滤器数量+ 1)*(订单数量) 虽然,正如文章所讨论的那样,可能有理由仍然可能使用复合索引 - 实际上,存在时间/空间权衡。