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

Rom*_*huk 4 postgresql defragmentation fragmentation

我发现,我们如何解决在SQL Server这个问题在这里-但我怎么能做到这一点在PostgreSQL的?

Lau*_*lbe 9

通常,您根本不必担心这一点。

但是,如果有大量删除或更新,或者持续变化率太高以至于 autovacuum 跟不上,你可能会得到一个严重膨胀的索引。

确定pgstattuple扩展名的工具:

CREATE EXTENSION pgstattuple;
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

这个指数非常好(从未使用过):它只有 14% 的膨胀。

请注意,默认情况下索引创建时的 afillfactor为 90,也就是说,索引块不会被 填充到 90% 以上INSERT

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

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

  • 在大索引上使用 REINDEX 时要小心,因为会在父表上获得写锁。在实时站点上实现相同结果的一种策略是在相同的表和列上同时构建索引,但使用不同的名称,然后删除原始索引并重命名新索引。此过程虽然要长得多,但不需要对活动表进行任何长时间运行的锁定。https://devcenter.heroku.com/articles/postgresql-indexes#managing-and-maintaining-indexes (3认同)
  • @RohitTaneja PostgreSQL v12 有 `REINDEX CONCURRENTLY` 这使得这更容易。 (2认同)