PostgreSQL有一種介於正常表和臨時表之間的類型表,稱之為unlogged表,在該表新建的索引也屬於unlogged,該表在寫入數據時候並不將數據寫入到持久的write-ahead log文件中,在數據庫異常關機或者異常崩潰后該表的數據會被truncate掉,但是在寫入性能上會比正常表快幾倍。
分別測試正常表和unlogged表數據插入速度區別
uber_geocoder=# \dt+ List of relations Schema | Name | Type | Owner | Size | Description --------------------------+------------------------+-------+----------+--------+------------- uber_geocoder_tw_15q3_v2 | compiling_info | table | postgres | 16 kB | uber_geocoder_tw_15q3_v2 | data_process_reports | table | postgres | 16 kB | uber_geocoder_tw_15q3_v2 | info | table | postgres | 16 kB | uber_geocoder_tw_15q3_v2 | twn_addr_compact | table | postgres | 774 MB | (4 rows) uber_geocoder=# \timing Timing is on.
uber_geocoder=# create table twn_addr_compact_loggod as select * from twn_addr_compact ; SELECT 258902 Time: 977250.581 ms
可以看到在新建正常表並插770M的數據的情況下耗時近16分鍾
新建一張unlogged表並插入770M數據進行測試
uber_geocoder=# create unlogged table twn_addr_compact_unloggod as select * from twn_addr_compact ; SELECT 258902 Time: 300683.321 ms
可以看到在同等條件下unlogged表的插入速度為5分鍾,性能提高了三倍。
感興趣的可以將postgres進程kill掉,然后再啟動數據庫,就會發現我們剛才創建的unlogged表數據丟失。
如何查看當前數據庫中所有的unlogged表
uber_geocoder=# select n.nspname as schema_name,c.relname as table_name from pg_catalog.pg_namespace n, pg_catalog.pg_class c where c.relnamespace=n.oid and n.nspname != 'pg_toast' and c.relkind='r' and c.relpersistence = 'u'; schema_name | table_name --------------------------+--------------------------- edbstore | emp uber_geocoder_tw_15q3_v2 | twn_addr_compact_unloggod (2 rows)
如果需要批量將unlogged表修改為正常的表,則執行如下
uber_geocoder=# select 'ALTER TABLE'||' '||concat(n.nspname,'.' ,c.relname)||' '||'SET LOGGED ;' AS convert_logged_sql from pg_catalog.pg_namespace n, pg_catalog.pg_class c where c.relnamespace=n.oid and n.nspname != 'pg_toast' and c.relkind='r' and c.relpersistence = 'u'; convert_logged_sql ----------------------------------------------------------------------------- ALTER TABLE edbstore.emp SET LOGGED ; ALTER TABLE uber_geocoder_tw_15q3_v2.twn_addr_compact_unloggod SET LOGGED ; (2 rows)
select n.nspname ||'.'|| c.relname as table_name, pg_table_size(n.nspname ||'.'|| c.relname) as table_size from pg_catalog.pg_namespace n, pg_catalog.pg_class c where c.relnamespace=n.oid and n.nspname != 'pg_toast' and c.relkind='r' and c.relpersistence = 'u' order by table_size desc;