ID、UUID 和“deleted_at”列,如何避免性能下降?

Dar*_*ter 1 postgresql database-design primary-key index-tuning uuid

考虑PostgreSQL上的这张表,但有数千条记录:

\n\n
| id |    uuid | color    | ... |          deleted_at |\n|----|---------|----------|-----|---------------------|\n| 1  | 4fc1... | red      | ... | 2020-01-01 13:00:00 |\n| 2  | 4fc1... | gray     | ... | 2020-01-01 13:00:00 |\n| 3  | 4fc1... | blue     | ... |                null |\n| 4  | 4fc1... | red      | ... |                null |\n| 5  | 4fc1... | blue     | ... | 2019-12-03 00:45:00 |\n
Run Code Online (Sandbox Code Playgroud)\n\n

目的:

\n\n
    \n
  • id(自动增量)用作主键和主要挂钩,以与其他表一起使用 JOIN。
  • \n
  • uuid是用于识别记录的面向公众的值。
  • \n
  • deleted_at(timestamp|null) 用于检查记录被删除的时间,并进行相应的过滤。
  • \n
\n\n

80% 的查询是使用以下方式完成的:

\n\n
    \n
  • WHERE [id] = ? AND WHERE [deleted_at] NOT NULL
  • \n
  • WHERE [uuid] = ? AND WHERE [deleted_at] NOT NULL
  • \n
\n\n

当数据库变大时,我可以看到性能下降,因为这些列没有索引,除了id设置为主键(自动增量)但沿deleted_at列使用的列之外。

\n\n

INSERT/UPDATE操作有点少,而且DELETE几乎不存在。

\n\n

我想到了复合主键并为id+deleted_at和制作两个索引uuid+deleted_at,但我不确定,因为INSERT/UPDATE考虑到现在有两个索引而不仅仅是一个主键,这可能会阻碍操作。

\n\n
\n\n

如何加速对该表的查询?

\n\n

更新 1:我考虑使用 ID 和 UUID,因为我有连接到三个表的表,因此三个 UUID = 128\xc3\x973 位,而三个 ID = 64\xc3\x973 位。但我可以用 192 位来换取一致性。

\n

小智 5

where id = ?无论表的大小如何,使用主键进行检索在时间上几乎是恒定的。使用 AND 添加条件不会改变这一点(OR尽管使用会是另一回事)

如果您需要使用 uuid 列上的条件进行相同的查询性能,请也为其创建一个(唯一)索引。

如果您始终查询,=则无需向索引添加其他列。创建包含的附加复合索引(id, deleted_at)不会提高查询速度。

如果有的话,过滤(部分)索引可能会有所帮助:

create unique index on (id) where deleted_at is null;
create unique index on (uuid) where deleted_at is null;
Run Code Online (Sandbox Code Playgroud)

但只有当删除的行多于未删除的行时,这才有用。


创建id, deleted_at主键似乎是完全错误的,因为这意味着您可以拥有多个具有相同值的行id- 这几乎不是您所期望的。