普通的索引膨脹處理比較簡單,主鍵的索引膨脹也不復雜,只是在新舊索引交替時有一些小處理。本試驗在primary key上通過CONCURRENTLY
建立第二索引來解決索引膨脹問題,適用9.3、9.4,其他版本使用前請實際測試。
創建測試表
Table "swrd.mytbl"
Column | Type | Modifiers
--------+-----------------------------+----------------------------------------------------
id | integer | not null default nextval('mytbl_id_seq'::regclass)
val | timestamp without time zone | default now()
Indexes:
"mytbl_pkey" PRIMARY KEY, btree (id)
生成測試數據
生成測試數據步驟略,這里為了清楚看到測試的情況,生成10000000條。
swrd=# SELECT COUNT(*) FROM mytbl;
count
----------
10000000
(1 row)
創建第二索引
在id上創建第二索引,記得使用CONCURRENTLY參數
swrd=# CREATE UNIQUE INDEX CONCURRENTLY ON mytbl USING btree(id);
CREATE INDEX
可以看到id字段上同時有兩個索引mytbl_pkey和mytbl_id_idx
swrd=# SELECT schemaname,relname,indexrelname,pg_relation_size(indexrelid) AS index_size,idx_scan,idx_tup_read,idx_tup_fetch FROM pg_stat_user_indexes WHERE indexrelname IN (SELECT indexname FROM pg_indexes WHERE schemaname = 'swrd' AND tablename = 'mytbl');
schemaname | relname | indexrelname | index_size | idx_scan | idx_tup_read | idx_tup_fetch
------------+---------+--------------+------------+----------+--------------+---------------
swrd | mytbl | mytbl_pkey | 224632832 | 0 | 0 | 0
swrd | mytbl | mytbl_id_idx | 224641024 | 0 | 0 | 0
(2 rows)
替換索引
開啟事務刪除主鍵索引同時將第二索引更新為主鍵的約束
swrd=# begin;
BEGIN
swrd=# ALTER TABLE mytbl DROP CONSTRAINT mytbl_pkey;
ALTER TABLE
swrd=# ALTER TABLE mytbl ADD CONSTRAINT mytbl_id_idx PRIMARY KEY USING INDEX mytbl_id_idx;
ALTER TABLE
swrd=# END;
COMMIT
檢查測試表的索引,可見現在只有第二索引了
swrd=# SELECT schemaname,relname,indexrelname,pg_relation_size(indexrelid) AS index_size,idx_scan,idx_tup_read,idx_tup_fetch FROM pg_stat_user_indexes WHERE indexrelname IN (SELECT indexname FROM pg_indexes WHERE schemaname = 'swrd' AND tablename = 'mytbl');
schemaname | relname | indexrelname | index_size | idx_scan | idx_tup_read | idx_tup_fetch
------------+---------+--------------+------------+----------+--------------+---------------
swrd | mytbl | mytbl_id_idx | 224641024 | 0 | 0 | 0
(1 row)
檢查表的定義
檢查表定義,可以看到與最初建表時是一樣的
swrd=# \d+ mytbl
Table "swrd.mytbl"
Column | Type | Modifiers | Storage | Stats target | Description
--------+-----------------------------+----------------------------------------------------+---------+--------------+-------------
id | integer | not null default nextval('mytbl_id_seq'::regclass) | plain | |
val | timestamp without time zone | default now() | plain | |
Indexes:
"mytbl_id_idx" PRIMARY KEY, btree (id)