PGSQL性能優化
pgsql優化一般考慮2個指標,一個是響應時間,一個是吞吐量
pgsql的性能優化涉及到多個層面,有硬件,有操作系統,有文件系統
我們首先從硬件開始分析,主要分析CPU,內存,存儲
一、CUP有不同的體系結構,其性能是不一樣的。
1.SMP/UMA:多CPU對稱工作,無主次之分,共享內存。性能好,貴。缺點:CPU數量受限制,過多CUP會造成訪問內存衝突。
2.NUMA:多CPU模塊,各CPU獨立享有自己的內存,也可以訪問其他CPU的內存,但是速度慢。典型代表X86系列
MPP:多個SMP聯網組成
具體可以參考 https://www.cnblogs.com/yubo/archive/2010/04/23/1718810.html
二、內存有不同的種類,主要有以下類型
SRAM:靜態隨機存儲器。速度快,造價高,不能大規模使用,一般用於CPU 緩存。
SDRAM:同步動態隨機存儲器。工作時需要同步時鐘。
DDR:雙倍數據傳輸速率的SDRAM,DDR是Double Data Rate 縮寫。目前主流爲DDR4.
服務器內存可以參考https://www.idcbest.com/servernews/11002265.html
三、硬盤有不同的接口,不同的接口性能也不一樣。常見的以下三種
1.ATA系列,包括比較老的硬盤接口,例如,IDE( Integrated Driver Electronics) SATA 2.0, 帶寬3Gb/s ,傳輸速度300MB/s, 數據線最大長度1.5米
2.SCSI系列“Small Computer System Interface”(小型計算機系統接口),Ultra320 SCSI 傳輸速率320MB。更穩定,更可靠。
3.FC接口:光纖接口的硬盤。帶寬4Gb,8Gb
另外硬盤還分不同的存儲介質
HDD:普通機械硬盤。SSD:固態硬盤 讀寫速度相差數倍。
然後,我們從操作系統-文件系統進行分析; EXT2,EXT3,EXT4,XFS
EXT4,
EXT4是Linux系統下的日誌文件系統,是EXT3文件系統的後繼版本。
(1)Ext4的文件系統容量達到1EB,而文件容量則達到16TB
(2)理論上支持無限數量的子目錄
(3)Ext4文件系統使用64位空間記錄塊數量和i-節點數量
(4)Ext4的多塊分配器支持一次調用分配多個數據塊
XFS
1)根據所記錄的日誌在很短的時間內迅速恢復磁盤文件內容
(2)採用優化算法,日誌記錄對整體文件操作影響非常小
(3) 是一個全64-bit的文件系統,它可以支持上百萬T字節的存儲空間
(4)能以接近裸設備I/O的性能存儲數據
XFS比EXt3有3-30%的性能提升,一般建議Postgresql部署到XFS文件系統上。
IO調優:
1.打開noatime。
每個文件都有ctime,mtime,atime 。pgsql通常不使用這三個屬性。尤其是atime可以禁用。
2.調整預讀
檢查預讀設置大小,blockdev --getra /dev/sda (根據自己系統修改)
返回值8192,表示預讀這麼多個扇區,每個扇區512字節,即0.5M. 所以這裏8192表示4M預讀。
一般採取默認即可,如果返回是256,可用增大此值。
接着從數據庫配置進行分析
1內存配置優化
shared_buffers:共享緩衝區的大小。根據物理可用內存調整,推薦物理內存的四分之一,不超過總內存的二分之一。
work_mem:爲每個進程單獨分配的內存,主要用於排序,hash操作。如果業務中排序操作比較多,可用增加此項值。
maintenance_work_mem:也是爲每個進程單獨分配的內存,但主要用於維護操作,如vacuum,create index。
huge_pages:巨型頁面的使用會導致更小的頁面表以及花費在內存管理上的 CPU 時間更少,從而提高性能。
2預寫日誌優化
對數據文件進行修改時,先把這些操作寫到日誌中,數據庫文件修改後的髒頁不必馬上刷新到磁盤中,如果出現了崩潰,可用重做記錄在日誌中的操作,從而恢復數據庫。
一些WAL相關的參數會影響到數據庫性能。
檢查點發生的頻率
checkpoint_timeout : 按照指定的時間間隔生成檢查點。合理的範圍在 30 秒到 1 天之間。默認是 5 分鐘(5min
)
checkpoint_completion_target:爲了避免檢查點產生太多的IO操作,導致系統性能出現大的抖動,可以讓Postgresql在平時儘快平均的把髒頁刷新到磁盤中,而不必等到檢查點時,才發現需要寫太多的髒頁,這個機制有參數checkpoint_completion_target來控制,默認值爲0.5. 也就是在兩個檢查點間隔的0.5倍時間內完成所有髒頁的刷新。
從數據庫設計分析
索引
聚簇原理:
聚簇是指:如果一組表有一些共同的列,則將這樣一組表存儲在相同的數據庫塊中;聚簇還表示把相關的數據存儲在同一個塊上。利用聚簇,一個塊可能包含多個表的數據。概念上就是如果兩個或多個表經常做鏈接操作,那麼可以把需要的數據預先存儲在一起。聚簇還可以用於單個表,可以按某個列將數據分組存儲。 更加簡單的說,比如說,EMP表和DEPT表,這兩個表存儲在不同的segment中,甚至有可能存儲在不同的TABLESPACE中,因此,他們的數據一定不會在同一個BLOCK裏。而我們有會經常對這兩個表做關聯查詢,比如說:select * from emp,dept where emp.deptno = dept.deptno .仔細想想,查詢主要是對BLOCK的操作,查詢的BLOCK越多,系統IO就消耗越大。如果我把這兩個表的數據聚集在少量的BLOCK裏,查詢效率一定會提高不少。
PostgreSQL支持基本的表劃分
劃分指的是將邏輯上的一個大表分成一些小的物理上的片。劃分有很多益處
在某些情況下查詢性能能夠顯著提升,特別是當那些訪問壓力大的行在一個分區或者少數幾個分區時。劃分可以取代索引的主導列、減小索引尺寸以及使索引中訪問壓力大的部分更有可能被放在內存中。
查詢或更新訪問一個分區的大部分行時,可以通過該分區上的一個順序掃描來取代分散到整個表上的索引和隨機訪問,這樣可以改善性能。
如果批量操作的需求是在分區設計時就規劃好的,則批量裝載和刪除可以通過增加或者去除分區來完成。執行ALTER TABLE DETACH PARTITION
或者使用DROP TABLE
刪除一個分區遠快於批量操作。這些命令也完全避免了批量DELETE
導致的VACUUM
開銷。
很少使用的數據可以被遷移到便宜且較慢的存儲介質上。
當一個表非常大時,劃分所帶來的好處是非常值得的。一個表何種情況下會從劃分獲益取決於應用,一個經驗法則是當表的尺寸超過了數據庫服務器物理內存時,劃分會爲錶帶來好處
PostgreSQL對下列分區形式提供了內建支持:
範圍劃分
表被根據一個關鍵列或一組列劃分爲“範圍”,不同的分區的範圍之間沒有重疊。例如,我們可以根據日期範圍劃分,或者根據特定業務對象的標識符劃分。
列表劃分
通過顯式地列出每一個分區中出現的鍵值來劃分表
哈希分區
通過爲每個分區指定模數和餘數來對錶進行分區。每個分區所持有的行都滿足:分區鍵的值除以爲其指定的模數將產生爲其指定的餘數。