Google App Engine数据存储区中的索引和索引条目限制

时间:2015-01-23 14:59:31

标签: database google-app-engine indexing google-cloud-datastore

我在理解GAE数据存储区中索引的工作方式时遇到了一些问题,特别是对我来说真的不清楚的是与索引相关的限制。
根据我的理解,可以在datastore-indexes.xml文件中创建一些自定义索引,此外,数据存储区将生成一些自动索引以匹配用户查询。
第一个问题是:"索引数量"配额页面(https://cloud.google.com/appengine/docs/quotas#Datastore)中定义的配额限制仅参考datastore-indexes.xml中定义的自定义索引,或者它是否也适用于自动生成的索引?

另一个概括我的概念是单个查询的"索引条目" 假设我没有多维属性(即不是列表),我有一些实体" KindA"。然后我定义了两组实体属性:
  - Group1:具有仲裁名称和布尔值的属性
  - Group2:具有arbitray name和double值的属性

在我的世界中,任何KindA实体最多可以拥有Group1的N个属性和Group2的N个属性。对于任何属性P,创建索引表,并且具有该P集的每个实体将在P索引表中添加一行(右?)。因此,最初任何KindA实体将为每个最大值具有1个条目。 2N属性(因此每个实体总共最多2N个索引条目)对吗? 如果这是正确的,那么我可以创建一个具有有限数量的属性的实体,但这很奇怪,因为我总是读到一个实体可以拥有无​​限的属性......(不考虑大小限制)。
但是现在让我们假设我的应用程序允许用户使用对Group1属性(布尔值1)的任意长序列AND过滤器来查询KindA实体。因此,人们可以查询类似的内容:

find all entities in KindA where prop1=true AND prop2=true ... AND propM = true  

这种情况下查询只包含相等性,因此不需要自定义索引(https://cloud.google.com/appengine/docs/python/datastore/indexes#Index_configuration)。

但是如果我想使用GroupB的属性订购怎么办?在这种情况下,我需要一个索引用于任何不同的查询权限(在过滤属性名称的组合方面不同)? 在我的developmnet服务器中,我试过没有指定任何自定义索引,GAE为我生成它们(但是每次重新启动以前生成的索引都会被删除)。在这种情况下,一个SignA KindA实体在单个查询索引中有多少索引条目?我说1,因为GAE文档说的是:

  

该属性也可能包含在索引配置文件(index.yaml)中声明的其他自定义索引中。如果实体没有列表属性,则每个此类自定义索引(对于非祖先索引)最多只有一个条目,或者每个实体的祖先(对于祖先索引)最多只有一个条目

因此,理论上如果N是有限的,那么对于实体的最大索引条目数而言,我是安全的。 (https://cloud.google.com/appengine/docs/java/datastore/#Java_Quotas_and_limits)是不是?

但接收超过200个不同的查询呢?它是否导致GAE自动生成200多个自定义索引(一个用于不同的查询)?如果是,这些索引会自动生成影响索引号限制(即200)吗? 如果是,那么我就不能让用户这样做(恕我直言)非常基本的查询。我误解了什么吗?

1 个答案:

答案 0 :(得分:2)

首先,我试图理解你发现难以理解的问题。

200索引限制仅计入您使用查询定义的索引(或由devappserver自动定义的索引)。这意味着将为索引属性单独创建的索引不计入此限制。

在为每个索引属性创建的2N自动索引中,这是正确的。

只要您没有超过每个实体1MB的限制,您就可以在任何实体中索引任意数量的属性。但是......这实际上取决于存储的属性的内容。

对于在索引属性上为您创建的索引...您实际上没有实际限制而不是增加成本,因为每个实体的写入和存储将为每个添加的属性增加。

使用排序顺序时,使用自动索引时,您只能使用一种排序顺序。更多排序顺序将需要复合索引(您的自定义索引)。因此,如果您已经在使用相等过滤器,则无论如何都需要自定义索引。

所以,是的,在您的示例中,devapp服务器将为您将要执行的每个查询创建一个复合索引。但是,您可以通过删除不需要的索引来手动减少此索引。查询计划程序可以使用查询时间通过合并不同的索引来查找结果,如下所述:

https://cloud.google.com/appengine/articles/indexselection

是的,index.yaml上的每个索引定义都将计入200限制。

当你知道如何编写gae应用程序时,我发现你真的不会过多地使用复合索引。您需要平衡用户需要做什么和不做什么。并且还可以在执行查询副作业之间进行平衡,或者只是查询所有内容并按代码进行过滤(这实际上取决于您在该特定类型中可以拥有的最大实体数量)。

但是,如果您尝试向用户提供一些复杂的查询,那么数据存储可能不是您的选择。