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

Indexes and indexes entries limits in Google App Engine Datastore

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

另一个让我难以理解的概念是 "index entry for a single query"。
假设我没有多维属性(即没有列表)并且我有一些实体 "KindA"。然后我定义两组实体属性:
- Group1:具有任意名称和布尔值的属性
- Group2:具有任意名称和双精度值的属性

在我的世界中,任何 KindA 实体最多可以拥有 Group1 的 N 个属性和 Group2 的 N 个属性。对于任何 属性 P,都会创建一个索引 table,并且每个具有该 P 集的实体都会在 P 索引 table 中添加一行(对吗?)。因此,最初任何 KindA 实体都将有 1 个条目用于每个最大值。 2N 个属性(因此每个实体总共最多 2N 个索引条目)对吗?
如果这是正确的,那么我可以创建一个具有有限数量属性的实体,但这很奇怪,因为我一直读到一个实体可以具有无限的属性......(不考虑大小限制)。
但是,现在假设我的应用程序允许用户在 Group1 的属性(布尔值一)上使用任意长的 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 会为我生成它们(但是任何时候我重新启动之前生成的索引都会被删除)。在这种情况下,一个单独的 KindA 实体在单个查询索引中有多少个索引条目?我说 1 是因为 GAE 文档说:

The property may also be included in additional, custom indexes declared in your index configuration file (index.yaml). Provided that an entity has no list properties, it will have at most one entry in each such custom index (for non-ancestor indexes) or one for each of the entity's ancestors (for ancestor indexes)

因此理论上,如果 N 有限,我对 "Maximum number of index entries for an entity" (https://cloud.google.com/appengine/docs/java/datastore/#Java_Quotas_and_limits) 是安全的,对吗?

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

首先,我试图理解你的问题,但我觉得很难理解。

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

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

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

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

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

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

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

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

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

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