数据存储区真的需要索引吗?

Posted

技术标签:

【中文标题】数据存储区真的需要索引吗?【英文标题】:Are indexes really required in the datastore? 【发布时间】:2011-06-11 13:49:33 【问题描述】:

我对一些 GAE 文档感到有些困惑。虽然我打算添加索引以优化我的应用程序的性能,但我想澄清一下它们是仅出于此目的而建议的,还是真的需要它们。

查询找不到属性值 未编入索引的。这包括 标记为非的属性 索引,以及与属性 长文本值类型的值 (文本)或长二进制值类型 (斑点)。

带有过滤器或排序顺序的查询 属性永远不会匹配实体 其属性值为 Text 或 Blob,或用 该属性标记为未编入索引。 具有此类值的属性表现为 如果没有设置属性 查询过滤器和排序顺序。

来自http://code.google.com/appengine/docs/java/datastore/queries.html#Introduction_to_Indexes

第一段让我相信您根本无法对未索引的属性进行排序或过滤。但是,第二段让我认为这种限制只限于 Text 或 Blob 属性或特别注释为未索引的属性。

我很好奇这种区别,因为我有一些数字和字符串字段,我目前在生产环境中对其进行排序/过滤,这些字段没有索引。这些查询正在后台任务中运行,该任务大多不关心性能(宁愿在这种情况下针对大小/成本进行优化)。我是不是很幸运这些返回了正确的数据?

【问题讨论】:

【参考方案1】:

在 GAE 数据存储中,会自动为所有不可索引(明确标记或属于这些类型)的属性创建单个属性索引。

我认为该文档中的语言有点令人困惑。

当您想要按多个属性进行索引时(例如,按两个不同的属性排序),您只需要显式定义索引。

【讨论】:

太好了,谢谢,解决了很多困惑。这个自动索引默认是升序还是降序? @netmau5 自动索引适用于两个方向。您要查询的所有内容都必须编入索引。【参考方案2】:

不幸的是,在 GAE 中,如果该属性被标记为未索引

  num = db.IntegerProperty(required=True, indexed=False)

那么就不可能将它包含在自定义索引中...这会适得其反(我的代码从未使用大多数内置索引,但会占用大量空间)。但这就是 GAE 目前的工作方式。

Datastore Indexes - Unindexed properties:

注意:如果一个属性出现在由多个属性组成的索引中,那么将其设置为未索引将阻止它在组合索引中被编入索引。

【讨论】:

所以通过将未使用的列设置为 unidexed 会提高性能,对吧? @AvinashRaj 是的,将属性设置为未索引将使写入更快并降低存储成本。【参考方案3】:

在未明确输入 indexed=True 或 indexed=False 的情况下,切勿将属性添加到模型。索引占用大量资源:空间、写入操作成本以及执行 put() 时的延迟增加。即使 index=False,我们也永远不会在没有明确说明其索引值的情况下添加属性。节省了代价高昂的疏忽,并迫使人们始终考虑是否要编制索引。 (在某些时候,您会发现自己在诅咒您忘记覆盖默认值 = True 的事实。)GAE 工程师会通过不允许它默认为 True 恕我直言来提供出色的服务。如果我是他们,我根本不会提供默认值。 HTH。 -史蒂夫

【讨论】:

【参考方案4】:

如果您想在一个查询中使用两个或多个过滤器功能,则必须使用索引。 例如: Foobar.filter('foo =', foo).filter('bar =', bar) 如果您只使用一个过滤器进行查询,则无需使用自动生成的索引。 对于 Blob 和 Text,你不能为它们生成索引,即使你在 index.yaml 中指定了它,同时你也不能在它们中使用过滤器。 例如 类 Foobar(db.Model): 内容 = db.TextProperty() Foobar.filter('content =', content) 上面的代码将引发错误,因为 TextProperty 无法分配索引且无法匹配。

【讨论】:

关于“两个或多个过滤器功能[s]”,这不太正确。数据存储区使用内置索引自动支持多种查询,无需自定义索引。请参阅this page 上以App Engine provides automatic indexes for... 开头的部分。

以上是关于数据存储区真的需要索引吗?的主要内容,如果未能解决你的问题,请参考以下文章

在C++中,你真的会用new吗?

实体中的大量属性会影响数据存储区的读/写性能吗?

App Engine:如何“重置”数据存储区?

你真的了解mysql索引吗?

计算在 Google App Engine 数据存储区中计算分数和日期的索引

MySQL innodb引擎深入讲解