考虑以下数据存储实体:
public class Employee {
@Id String id;
@Index String userName
}
我的理解是,只有那些属于查询中过滤条件的属性才需要使用@Index
进行注释。数据存储区中的索引不是为了提高性能,而是为了获取数据。
id
是否也应@Index
注释id
进行查询?如果不是,数据存储区是否会自动为密钥创建索引?@Id
注释确保管理唯一性,但它没有索引属性的性能优势。是吗?id
的查询是否比上例中的userName
查询要快? 答案 0 :(得分:4)
<强> 1 强>
不,您不需要明确索引它。数据存储区使用您的密钥作为实体的主键(在Entities table中)。
2&amp; 3:强>
通过主键查询更有效(您只需要在主表上进行单次扫描,而不是在索引上进行扫描,然后在主表中进行查找。但是,它还允许您执行{{1}而不是查询:
Lookup
除了避免查询计划和索引扫描以查找此Employee e = ofy().load().type(Employee.class).id("<id>").now();
之外,这是Strongly Consistent。如果您不这样做,您可以编写一个新的Employee
,但在查询时不会真正看到它们。
虽然强一致性从应用程序正确性的角度来看很重要,但速度会慢一些。特别是,当您执行强一致性查找时,数据存储区可能需要与其他副本(在其他数据中心中)与catch up your entity group进行通信。
如果您对最终的一致性感到满意,则可以执行具有最终一致性的Employee
,以避免索引扫描和使用read policy来复制副本。在客观化中,这看起来像:
Lookup
注意:这个答案讲述了很多关于索引和表格的内容。一般来说,我建议不要在索引和表方面考虑数据存储(因为不是关系存储系统)。但是,它是在关系数据库上实现的,因此对回答您的问题非常有用。 This page有很多好的背景。
答案 1 :(得分:2)
@Id
确保Key
另外,请记住,如果您决定稍后添加@Index
注释,则只会为新实体创建,所有现有实体都将无法编入索引。这意味着您需要重新索引数据库,或者只有通过此字段使用过滤器从Query返回新记录。
答案 2 :(得分:0)
Objectify始终按键获取 - 如果运行查询,它只执行键查询,然后按id获取结果。这很有效,因为它具有缓存集成,这也意味着您可以获得准确的结果(因为数据非常一致,即使它们查询的结果不是很复杂)。您可以使用.hybrid(boolean)
方法对查询进行控制。
您无法按ID查询 - 您只能按键获取。如果您想这样做,则需要一个重复的索引字段,并对其进行查询。这是密钥在数据存储区中的工作方式的工件。