# 24.2. 定期重建索引

在某些情況下，使用 [REINDEX](https://docs.postgresql.tw/12/reference/sql-commands/reindex) 指令或一系列單獨的重建步驟定期重建索引是值得的。

已完全為空的 B-tree 索引頁面將被回收以供重複使用。但是，仍然存在空間使用效率低的可能性：如果頁面上除了少數索引鍵之外的所有索引鍵都已被刪除，則頁面仍然會被分配。因此，最終刪除每個範圍中的大多數但不是所有鍵的使用模式將會發現空間使用率不佳。對於此類使用模式，建議定期重建索引。

非 B-tree 索引中膨脹的可能性尚未具有很好的研究。所以在使用任何非 B-tree 索引類型時，定期監視索引的磁碟大小是個好主意。

此外，對於 B-tree 索引，新建構的索引比多次更新的索引要快一些，因為邏輯上相鄰的頁面通常在新建構的索引中也是物理上相鄰的。（這種考慮不適用於非 B-tree 索引。）為了提高存取速度，定期重建索引會是值得的。

在所有情況下，REINDEX 都可以很安全，簡單地使用。但由於該指令需要獨占資料表鎖定，因此通常最好使用一系列建立和替換步驟來執行索引重建。使用 CONCURRENTLY 選項支援 [CREATE INDEX](https://docs.postgresql.tw/12/reference/sql-commands/create-index) 的索引類型可以透過這種方式重新建立。如果成功並且結果索引有效，則可以使用 [ALTER INDEX](https://docs.postgresql.tw/12/reference/sql-commands/alter-index) 和 [DROP INDEX](https://docs.postgresql.tw/12/reference/sql-commands/drop-index) 的組合將原始索引替換為新建構的索引。當索引用於強制唯一性或其他約束時，可能需要使用 [ALTER TABLE](https://docs.postgresql.tw/12/reference/sql-commands/alter-table) 將現有限制條件與新索引強制執行的限制條件交換。 在使用之前仔細檢查這種多步驟重建方法，因為對這些索引透過這種方式重新建立索引可能有些限制，並且必須處理錯誤。
