| PostgreSQL 8.0.0 中文文件(轉譯自 PostgreSQL 中國 製作的簡體中文版本) | ||||
|---|---|---|---|---|
| Prev | Fast Backward | Chapter 13. 性能提升技巧 | Fast Forward | Next |
我們第一次填充資料庫時可能需要做大量的資料表插入。 下面是一些建議,可以盡可能高效地處理這些事情。
關閉自動提交,並且只在每次(資料拷貝)結束的時候做一次提交。 (在純 SQL 裡,這就意味著在開始的時候發出 BEGIN, 並且在結束的時候執行 COMMIT。有些客戶端的庫可能背著您幹這些事情, 這種情況下您必須確信只有在您要那些庫幹這些事情的時候它才做。) 如果您允許每個插入都獨立地提交,那麼 PostgreSQL 會為所增加的每行記錄做大量的處理。 在一個交易裡完成所有插入的動作的最大的好處就是,如果有一條記錄插入失敗, 那麼,到該點為止的所有已插入記錄都將被回滾,這樣您就不會很難受地面對一個只裝載了一部分資料的資料表。
使用 COPY 在一條命令裡裝載所有記錄, 而不是一連串的INSERT命令。COPY 命令是為裝載數量巨大的資料行優化過的; 它沒 INSERT 那麼靈活,但是在大量裝載資料的情況下,導致的過荷也少很多。 因為 COPY 是單條命令,因此填充資料表的時候就沒有必要關閉自動提交了。
如果您不能使用 COPY,那麼 使用 PREPARE 來建立一個準備好的 INSERT, 然後使用 EXECUTE 多次效率更高。 這樣就避免了重複分析和規劃 INSERT 的開銷。
請注意,在裝載大量資料行的時候,COPY 幾乎總是比 INSERT 快, 即使使用了 PREPARE 並且把多個 INSERT 命令綁在一個交易中也是這樣的。
如果您正在裝載一個新建立的資料表,最快的方法是建立資料表, 用COPY批量裝載,然後建立資料表需要的任何索引。 在已存在資料的資料表上建立索引要比遞增地更新所裝載的每一行記錄要快。
如果您對現有資料表進行增大操作,您可以刪除索引, 裝載資料表,然後重新建立索引。 當然,在缺少索引的期間,其他資料庫用戶的資料庫性能將有負面的影響。 並且我們在刪除唯一索引之前還需要仔細考慮清楚,因為唯一約束 提供的錯誤檢查在缺少索引的時候會消失.
在裝載大量的資料的時候,可以臨時增大 maintenance_work_mem 配置變量以便改進性能。 這是因為在從零開始建立一個 B-tree 索引地時候,現有的資料表需要進行排序。 允許融合排序使用更多的緩衝頁面意味著需要少一些的融合回合數。
臨時增大 checkpoint_segments 配置變量也可以讓大量資料裝載得更快。 這是因為向 PostgreSQL 裡面裝載大量的資料可以導致檢查點操作 (由配置變量 checkpoint_timeout 聲明) 比平常更加頻繁發生。在發生一個檢查點的時候,所有髒資料都必須刷新到磁盤上。 透過在大量資料裝載的時候臨時增加 checkpoint_segments, 所要求的檢查點的數目可以減少。
不管甚麼時候,如果您在增加或者更新了大量資料之後, 執行 ANALYZE 都是個好習慣。 執行 ANALYZE(或者 VACUUM ANALYZE) 可以保證規劃器有最新的資料表的資料的統計。 如果沒有統計資料或者統計資料太陳舊,那麼規劃器可能選擇很差勁的查詢規劃,導致檢索您的資料表的查詢性能的惡化。