我应该使用复合主键来加速 PostgreSQL 中基于时间戳的选择吗?
Posted
技术标签:
【中文标题】我应该使用复合主键来加速 PostgreSQL 中基于时间戳的选择吗?【英文标题】:Should I use composite primary key to speed up timestamp-based select in PostgreSQL? 【发布时间】:2020-03-31 05:59:52 【问题描述】:我在 PostgreSQL 11 中有一张表 worker_activity_events
:
worker_id integer not null
栏目2:created_at timestamp default now() not null
第三栏:event_type text
每条记录必须有一个worker_id
和created_at
。我想经常运行的查询是
SELECT * FROM worker_activity_events
WHERE worker_id = $1
AND created_at BETWEEN $2 AND $3
为了快速运行查询,添加PRIMARY KEY(worker_id, created_at)
是否合理?
一个问题可能是:在一个示例时间戳,生成了同一个工作人员的 2 个事件,第二个事件将因为主键 (worker_id, created_at) 被违反而被拒绝。假设在我的应用上我可以防止这种情况发生。
【问题讨论】:
【参考方案1】:从数据库理论的角度来看,我会说您应该根据真正唯一标识行的内容来定义主键,而不是基于性能考虑。
因此,如果没有自然主键,请定义一个人工主键,并使用CREATE INDEX
创建查询所需的索引。
但是,在现实生活中,您有时不得不偏离理论理想。如果性能考虑要求您拥有尽可能少的索引,并且您可以使用建议的主键,那就去吧。否则坚持理论 - 过早优化是万恶之源。
【讨论】:
【参考方案2】:如果不考虑这个因素,主键会是什么?
您可以在(worker_id, created_at)
上创建复合索引。没有理由将其声明为主键只是为了将其作为索引。
但您也可以在(worker_id, created_at, event_type)
上创建索引,甚至可能是主键。该索引应该能够做其他索引可以做的所有事情,甚至更多。除非 event_type 非常宽,否则它不应该大很多。一个缺点是,如果您更新行以仅更改 event_type(这似乎不太可能,仅基于列名),此索引将禁用 Heap-Only-Tuple 优化。
【讨论】:
以上是关于我应该使用复合主键来加速 PostgreSQL 中基于时间戳的选择吗?的主要内容,如果未能解决你的问题,请参考以下文章