Normally you don't have to worry about that at all.
However, if there has been a mass delete or update, or the sustained change rate was so high that autovacuum couldn't keep up, you may end up with a badly bloated index.
The tool to determine that id the pgstattuple extension:
CREATE EXTENSION pgstattuple;
Then you can examine index bloat like this:
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
This index is in excellent shape (never used): It has only 14% bloat.
Mind that indexes are by default created with a fillfactor of 90, that is, index blocks are not filled to more than 90% by INSERT.
It is hard to say when an index is bloated, but if leaf_fragmentation exceeds 50-60, it's not so pretty.
To reorganize an index, use REINDEX.
Normally you don't have to worry about that at all.
However, if there has been a mass delete or update, or the sustained change rate was so high that autovacuum couldn't keep up, you may end up with a badly bloated index.
The tool to determine that id the pgstattuple extension:
CREATE EXTENSION pgstattuple;
Then you can examine index bloat like this:
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
This index is in excellent shape (never used): It has only 14% bloat.
Mind that indexes are by default created with a fillfactor of 90, that is, index blocks are not filled to more than 90% by INSERT.
It is hard to say when an index is bloated, but if leaf_fragmentation exceeds 50-60, it's not so pretty.
To reorganize an index, use REINDEX.
With PostgreSQL index defragmentation should generally be handled automatically by the Autovacuum daemon. If you don't use the autovacuum daemon, or if it isn't able to keep up, you can always reindex problematic indexes.
Determining which indexes may be badly fragmented isn't particularly straight forward and it's discussed at length in this blog post and in this PostgreSQL wiki article.
I think leaf_fragmentation is the percentage of leaf pages where the following leaf page has a lower block number. This is relevant for performance, because for an index range scan on a fragmented index, the kernel won't detect a sequential scan, and its read-ahead mechanism is defied.
But for me, the more important column is avg_leaf_density. If that is too low, your index is bloated and inefficient.
The question what values are OK is a difficult one. I'd say that anything over 30% is fine, but 20% is not terrible either.
If you are unsure whether to rebuild an index or not, ask yourself the following:
If you observe the bloat over time, does it continuously increase? If yes, that is bad, and a
REINDEXis probably necessary.If the bloat stays high, but does not increase,
REINDEXonce and observeDoes that improve the performance of your application?
Does the index get bloated again until it is as bloated as before?
"No" to the second question would suggest to leave the index alone.
If you decide to REINDEX, explore if more aggressive autovacuum settings on the affected table can keep the bloat down.
It Depends™. Fragmentation by itself isn't good or bad, it's just a property of the index. If all your queries scan the index for a unique value, they will read a handful of pages, at most, in any case, so it doesn't matter if the index is fragmented. If, on the other hand, you routinely scan wide ranges of pages, lots of empty pages would probably hurt. You'll need to look at the I/O statistics to decide what's acceptable.