Nox*_*lle 2 postgresql benchmark index
我有一个尚未升级的旧数据库(postgres 10.15)。一张有问题的表上有一些大型索引,其中一些索引已损坏并需要重新索引。由于它不在版本 12+ 上,我无法同时重新索引表(这意味着我需要非并发地执行此操作,这需要表写锁) - 所以我想知道如何进行一些粗略计算重新索引需要很长时间,这样我就可以计划一些维护。我的大部分研究最终都以“只使用 pg_stat_progress_create_index!(这在 10 中不可用)结束,或者人们只是说同时使用。
该表约为 200GB,索引有 7 个,每个索引 14GB(根据 pg_relation_size)。对于此任务,我可以在数据库上获得约 900M/s 的恒定读取速率。是否有一个简单的指标可以用来确定需要读取多少数据才能完全重新索引?
您可以通过以下方式创建具有不同名称的新索引
create index concurrently index_new on ...
Run Code Online (Sandbox Code Playgroud)
然后删除损坏的索引
drop index concurrently index_old;
Run Code Online (Sandbox Code Playgroud)
然后您可以将新索引重命名为旧名称:
alter index index_new rename to index_old;
Run Code Online (Sandbox Code Playgroud)
后者将需要锁定,但需要锁定后的几毫秒运行时间。所以你不需要因为写锁而停机。
索引的定义可以通过命令获取pg_dump -s -t tablename --no-acl
reindex concurrently
这与幕后执行的过程完全相同。但reindex concurrently
便宜一点,因为索引重命名阶段不需要锁。
众所周知,pg_repack
具有使用选项重新索引表的功能--only-indexes
。此选项以同时创建+删除索引的方式实现。
是否有一个简单的指标可以用来确定需要读取多少数据才能完全重新索引?
那么,任何没有索引创建的索引concurrently
都会按顺序读取整个表(concurrently
将读取表两次)。其他事情取决于访问方法。Btree 将对所有活动元组进行排序。这是创建索引最耗时的部分,对于大型索引,工作将在临时文件中完成(记住增加maintenance_work_mem
)。这部分还取决于数据类型和值。选择性较小的文本(例如某些status
字段)的构建速度将明显慢于整数序列。
我无法估计,除了一个:测量某些数据样本上索引的创建时间:
create table estimate_table as (
select * from tablename
where created_at > '2020-01-01'
);
\dt+ estimate_table
\timing on
create index on estimate_table ...
Run Code Online (Sandbox Code Playgroud)
重新索引只是索引创建的一种特殊形式。嗯,还有很重要的一点:在资源使用方面reindex table
与几个没有区别。通过调用表上的每个单独索引来实现。因此,具有 5 个索引的表将被扫描 5 次。reindex index
reindex table
reindex_index