我遇到以下情况
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”上有多少个索引记录?
我还不太明白这个索引的东西,并且正在杀了我。非常感谢您的帮助:)
答案 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)
根据您提供的标准,您只需要创建三个复合索引:a,x,items,-date
,a,y,items,-date
,a,z,items,-date
。请注意,list属性为列表中的每个属性创建索引条目。
每个实体都有总 5000个索引条目的限制。如果你只有三个复合索引,那么它的5000/3 = 1666(单个列表属性的上限为1000)。
仅在三个复合指数的情况下,3 * 1000 = 3000。
注意:以上假设您没有每个属性的内置索引(=属性保存为未编制索引)。否则,您需要考虑2N处的内置索引,其中N为单个属性的数量(2表示asc,desc)。在你的情况下,这将是2 *(5 + no_items),因为items
是一个列表属性,每个条目都创建一个索引条目。
答案 2 :(得分:1)
另请参阅https://developers.google.com/appengine/articles/indexselection,其中介绍了App Engine(相对较新的)改进的查询规划功能。基本上,您可以减少所需的索引条目数量:(过滤器数量+ 1)*(订单数量) 虽然,正如文章所讨论的那样,可能有理由仍然可能使用复合索引 - 实际上,存在时间/空间权衡。