在布尔值上建立索引是个好主意吗?

Is it a good idea to have an index on a boolean?

我有一个带有布尔字段 IsNew 的 table,它指示相应的实体是否是新的。我想定期查询处于特定状态的所有实体。在布尔值(或枚举)上建立索引有什么影响?会不会制造热点? QPS 有什么限制吗?

二级索引在内部实现为 table,它具有基于声明的二级索引键的主键,以及二级索引中未明确提及的任何索引 table 键。所以,假设你有一个像这样的 table:

CREATE TABLE UserThings (
  UserId INT64 NOT NULL,
  ThingId INT64 NOT NULL,
  ...
  IsNew BOOL NOT NULL,
  ...
) PRIMARY KEY(UserId, ThingId), ...

然后你创建一个这样的索引:

CREATE INDEX UserThingsByIsNew ON UserThings(IsNew, ThingId)

这将创建一个内部 table,看起来像这样:

CREATE TABLE UserThingsByStatus_Index (
  IsNew BOOL,
  ThingId INT64 NOT NULL,
  UserId INT64 NOT NULL,
) PRIMARY KEY(new, ThingId, UserId), ...

因此,当您更新 UserThings 的行以更改 IsNew 列的值时,它将删除 UserThingsByIsNew_Index 中的旧行并插入一个额外的行。如果行的 IsNew 值变化频率很高,这往往会在索引中造成大量变动。这可能根本不是问题,但只有在 real-world 工作负载下持续测试您的场景才能真正知道。

如果您不经常更新实体的 IsNew 字段,那么您可能不会遇到任何 hot-spotting 问题。这就是为什么我之前提到 Cloud Spanner 还将原始的 table 键附加到索引的键:假设您的原始 table 行被 table 的 well-distributed键,则索引的 IsNew=true 和 IsNew=false 部分将具有相似的分布,不应引起热点。