我在Postgres 14.7中有以下表格
create table product
(
id uuid,
description varchar,
created_at timestamptz,
primary key (id)
);
create index idx__product__created_at on product(created_at);
这个表有数亿条记录,为了简化而省略了更多的列。现在,我想做以下更改:
alter table product
add column published_to_kafka timestamptz default null;
create index idx__product_published_to_kafka on product (created_at asc) where published_to_kafka is null;
我不能承受数据库的性能问题,即使是很短的一段时间,我担心索引的创建会使数据库变慢。
如果在执行索引创建命令时,数据库中的大多数记录的列published_to_kafka
都不为null,那么这会使索引创建的性能更快吗?
1条答案
按热度按时间guz6ccqo1#
我不能承受数据库的性能问题,即使是很短的一段时间,我担心索引的创建会使数据库变慢。
我认为您需要清楚“慢速数据库”和“锁定表”之间的区别--常规
CREATE INDEX
将锁定表,直到索引构建完成,暂时阻止用户获取某些数据。虽然这可能会被用户体验为缓慢的网页加载,但这实际上是一个短暂的中断,因为数据无法访问。如果您希望防止这种服务中断,则必须使用CREATE INDEX CONCURRENTLY
,它可以解决锁定行为。如果你真的关心索引构建的性能,我认为重要的是要记住,要创建索引,必须访问每一行,并且需要分析相关的列来创建索引。我们不能回避必须扫描每一行。但是,如果没有索引,您可能必须在
SELECT
期间扫描每一行(当然,除非您正在搜索具有唯一约束的列,并且前几行返回您要查找的内容)。当索引被构建时,索引的内容将存在于内存中(因为需要对内容进行排序),直到它准备好持久化到磁盘。因此,如果
maintenance_work_mem
不够大,一些排序操作将在磁盘上而不是在内存中完成,从而会降低CREATE INDEX
操作的速度。正如其他人在评论中提到的,如果您担心无法“承受数据库的性能问题,即使是短时间内”,您需要重新评估当前的硬件是否足以满足您的需求。如果
SELECT * FROM <table_to_be_indexed>
降低了数据库的速度,或者如果VACUUM <table_to_be_indexed>
降低了数据库的速度,那么您的硬件可能不适合您的需要。如果在执行索引创建命令时,数据库中的大多数记录的
published_to_kafka
列都不为空,那么这会使索引创建的性能更快吗?可能--您仍然需要遍历每一行,但排序可能会更快,因为需要排序的值更少。