如何在 PostgreSQL 中找出碎片索引并对其进行碎片整理?

Posted

技术标签:

【中文标题】如何在 PostgreSQL 中找出碎片索引并对其进行碎片整理?【英文标题】:How to find out fragmented indexes and defragment them in PostgreSQL? 【发布时间】:2019-02-25 22:24:19 【问题描述】:

我已经找到了如何在 SQL Server here 中解决这个问题 - 但是我如何在 PostgreSQL 中解决这个问题?

【问题讨论】:

【参考方案1】:

通常您完全不必担心这一点。

但是,如果发生了大规模删除或更新,或者持续更改率如此之高以至于 autovacuum 无法跟上,您最终可能会得到一个严重臃肿的索引。

确定pgstattuple 扩展名的工具:

CREATE EXTENSION pgstattuple;

然后你可以像这样检查索引膨胀:

SELECT * FROM pgstatindex('spatial_ref_sys_pkey');

-[ RECORD 1 ]------+-------
version            | 2
tree_level         | 1
index_size         | 196608
root_block_no      | 3
internal_pages     | 1
leaf_pages         | 22
empty_pages        | 0
deleted_pages      | 0
avg_leaf_density   | 64.48
leaf_fragmentation | 13.64

这个索引状态很好(从未使用过):它只有 14% 的膨胀。

请注意,默认情况下创建索引时使用 90 的 fillfactor,也就是说,INSERT 填充的索引块不会超过 90%。

索引何时膨胀很难说,但如果leaf_fragmentation 超过 50-60,那就不是那么漂亮了。

要重新组织索引,请使用REINDEX

【讨论】:

在大索引上使用 REINDEX 时要谨慎,因为会在父表上获得写锁。在实时站点上实现相同结果的一种策略是在相同的表和列上同时建立一个索引,但名称不同,然后删除原始索引并重命名新索引。这个过程虽然更长,但不需要对活动表进行任何长时间运行的锁定。 devcenter.heroku.com/articles/… @RohitTaneja PostgreSQL v12 有 REINDEX CONCURRENTLY,这让这更容易。【参考方案2】:

使用 PostgreSQL 索引碎片整理通常应由 Autovacuum daemon 自动处理。如果您不使用 autovacuum 守护程序,或者它无法跟上,您可以随时reindex problematic indexes。

确定哪些索引可能严重碎片化并不是特别简单,this blog post 和 in this PostgreSQL wiki article 对此进行了详细讨论。

【讨论】:

以上是关于如何在 PostgreSQL 中找出碎片索引并对其进行碎片整理?的主要内容,如果未能解决你的问题,请参考以下文章

在 PostgreSQL 12 上使用 WITH 查找唯一值、计算重复项并对其进行排名

如何管理在开发(而非测试)环境中使用多个微服务并对其进行模拟?

关闭 H2 数据库;紧凑与碎片整理?

如何在postgresql中循环字符串[]?

如何在 PostgreSQL 8.2(用于 Greenplum)中找到死元组(碎片)?

SQL Server数据库表索引碎片整理