咱們第一次填充數據庫時可能須要作大量的表插入。 下面是一些建議,能夠儘量高效地處理這些事情。php
關閉自動提交,而且只在每次(數據拷貝)結束的時候作一次提交。 (在純 SQL 裏,這就意味着在開始的時候發出 BEGIN, 而且在結束的時候執行 COMMIT。有些客戶端的庫可能揹着你幹這些事情, 這種狀況下你必須確信只有在你要那些庫幹這些事情的時候它才作。) 若是你容許每一個插入都獨立地提交,那麼 PostgreSQL 會爲所增長的每行記錄作大量的處理。 在一個事務裏完成全部插入的動做的最大的好處就是,若是有一條記錄插入失敗, 那麼,到該點爲止的全部已插入記錄都將被回滾,這樣你就不會很難受地面對一個只裝載了一部分數據的表。html
使用 COPY 在一條命令裏裝載全部記錄, 而不是一連串的INSERT命令。COPY 命令是爲裝載數量巨大的數據行優化過的; 它沒 INSERT 那麼靈活,可是在大量裝載數據的狀況下,致使的過荷也少不少。 由於 COPY 是單條命令,所以填充表的時候就沒有必要關閉自動提交了。sql
若是你不能使用 COPY,那麼 使用 PREPARE 來建立一個準備好的 INSERT, 而後使用 EXECUTE 屢次效率更高。 這樣就避免了重複分析和規劃 INSERT 的開銷。數據庫
請注意,在裝載大量數據行的時候,COPY 幾乎老是比 INSERT 快, 即便使用了 PREPARE 而且把多個 INSERT 命令綁在一個事務中也是這樣的。性能
若是你正在裝載一個新建立的表,最快的方法是建立表, 用COPY批量裝載,而後建立表須要的任何索引。 在已存在數據的表上建立索引要比遞增地更新所裝載的每一行記錄要快。優化
若是你對現有表增長大量的數據,可能先刪除索引,裝載表,而後從新建立索引更快些。 固然,在缺乏索引的期間,其餘數據庫用戶的數據庫性能將有負面的影響。 而且咱們在刪除惟一索引以前還須要仔細考慮清楚,由於惟一約束 提供的錯誤檢查在缺乏索引的時候會消失.spa
和索引同樣,"批量地"檢查外鍵約束比一行行檢查更高效。 所以,也許咱們先刪除外鍵約束,裝載數據,而後重建約束會更高效。 一樣,裝載數據和缺乏約束而失去錯誤檢查之間也有一個平衡。rest
在裝載大量的數據的時候,臨時增大 maintenance_work_mem 配置變量能夠改進性能。 這個參數也能夠幫助加速 CREATE INDEX 命令和 ALTER TABLE ADD FOREIGN KEY 命令。它不會對 COPY 自己有多大做用,因此這個建議只有在你使用上面的兩個技巧中的一個或兩個纔有效。orm
臨時增大 checkpoint_segments 配置變量也可讓大量數據裝載得更快。 這是由於向 PostgreSQL 裏面裝載大量的數據能夠致使檢查點操做 (由配置變量 checkpoint_timeout 聲明) 比日常更加頻繁發生。在發生一個檢查點的時候,全部髒數據都必須刷新到磁盤上。 經過在大量數據裝載的時候臨時增長 checkpoint_segments, 所要求的檢查點的數目能夠減小。htm
無論甚麼時候,若是你在增長或者更新了大量數據以後, 運行 ANALYZE 都是個好習慣。 運行 ANALYZE(或者 VACUUM ANALYZE) 能夠保證規劃器有最新的表的數據的統計。 若是沒有統計數據或者統計數據太陳舊,那麼規劃器可能選擇不好勁的查詢規劃,致使檢索你的表的查詢性能的惡化。
pg_dump 生成的轉儲腳本自動使用上面的若干個技巧, 但不是所有。要儘量快地裝載 pg_dump 轉儲, 咱們須要手工作幾個事情。(請注意,這些要點適用於恢復一個轉儲, 而不是建立一個轉儲的時候。一樣的要點也適用於使用 pg_restore 從 pg_dump 歸檔文件裝載數據的時候。)
缺省的時候,pg_dump 使用 COPY, 在它生成一個完整的模式和數據的轉儲的時候,它會很當心地先裝載數據,而後建立索引和外鍵。 所以,在這個狀況下,頭幾條技巧是自動處理的。你須要作的只是在裝載轉儲腳本以前設置合適的(也就是說,比正常情況要大的) maintenance_work_mem 值和 checkpoint_segments 值, 而後在裝載完成以後運行 ANALYZE。
只保存數據的轉儲仍然會使用 COPY,可是它不會刪除或者重建索引, 而且它不會自動修改外鍵。 [1] 所以,在裝載只有數據的轉儲的時候,是否使用刪除以及重建索引和外鍵等技巧徹底取決於你。 裝載數據的時候,增大 checkpoint_segments 仍然是有用的, 可是增大 maintenance_work_mem 就沒什麼必要了; 你只是應該在過後手工建立索引和外鍵的過後增大它。