在 Google 数据存储中,按键查询是否比索引 属性 查询更快?

Is query by key faster than query by indexed property in Google Datastore?

考虑以下数据存储实体:

public class Employee {
    @Id String id;
    @Index String userName
}

我的理解是,只有那些属于查询过滤条件的属性才需要用 @Index 注释。数据存储中的索引不是为了性能而是为了获取数据。

  1. id也要注解@Index才能被id查询吗?如果不是,数据存储是否自动为键创建索引?
  2. @Id 注释确保管理唯一性,但它与索引属性相比没有性能优势。是吗?
  3. 在上面的例子中,id 查询会比 userName 查询更快吗?
  1. 否,将自动创建
  2. @Id 确保它是 Key
  3. 找不到确认信息,但必须更快。而且它比查询便宜,get 读取 1 次,query 读取 2 次。参见 https://cloud.google.com/datastore/docs/pricing

此外,请记住,如果您决定稍后添加 @Index 注释,那么它将仅为新实体创建,所有现有实体都将取消索引。这意味着您需要重新索引数据库,或者只有新记录会从带有此字段过滤器的查询中返回。

1:

不,您不需要明确索引它。 Datastore 使用您的键作为实体的主键(在 Entities table 中)。

2 & 3:

按主键查询效率更高(您只需要对主键进行一次扫描 table,而不是先对索引进行扫描,然后再在主键中进行查找 table。但是,它还允许您执行 Lookup 而不是查询:

Employee e = ofy().load().type(Employee.class).id("<id>").now();

除了避免查询计划和索引扫描来查找这个Employee,这是Strongly Consistent。如果你不这样做,你可能会写一个新的 Employee 但当你查询它们时实际上看不到它们。

虽然 强一致性 从应用程序正确性的角度来看很重要,但它会更慢。特别是,当您进行强一致性查找时,Datastore 可能需要与其他副本(在其他数据中心)通信以 catch up your entity group.

如果您对最终一致性没问题,您可以执行具有最终一致性的 Lookup 以避免索引扫描 副本使用 read policy.在 objectify 中,这看起来像:

Employee e = ofy().consistency(Consistency.EVENTUAL).load()
    .type(Employee.class).id("<id>).now();

注意: 这个答案谈了很多关于索引和 table 的内容。一般来说,我建议不要从索引和 table 的角度考虑 Datastore(因为它 不是 关系存储系统)。但是,它是在关系数据库上实现的,对于回答您的问题非常有用。 This page 有很好的背景。

Objectify 总是通过键获取 - 如果您 运行 查询,它只进行键查询,然后通过 ID 获取结果。这很有效,因为它具有缓存集成,并且还意味着您可以获得准确的结果(因为数据是高度一致的,即使它们查询结果不是)。您可以在查询中使用 .hybrid(boolean) 方法来控制它。

您不能通过 id 查询 - 您只能通过 key 获取。如果你想这样做,你需要一个重复的索引字段,并对其进行查询。这是密钥在数据存储区中工作方式的产物。