postgresql 支援的數字類型包括整型,浮點,以及pg自己實作的numeric資料類型。
numeric可以存儲非常大的數字,超過2^17次方個數字長度。提升了精度的同時,也帶來了性能的損耗,不能充分利用cpu 的 “硬解碼”能力。
浮點類型就比numeric輕量很多,是以性能也會好很多,一倍左右。
在大資料的場合中,節約1倍的計算量是很可觀的哦,特别是在金融行業,涉及到大量的數值計算。
如果你玩過greenplum, deepgreen, vitessedb ,也能發現在這些資料庫産品的測試手冊中,會提到使用money, float8類型來替換原有的numeric類型來進行測試。可以得到更好的性能。
但是money, float8始終是有一定的弊端的,超出精度時,結果可能不準确。
那麼怎樣提升numeric的性能又不會得到有誤的結果呢?
我們可以使用fexeddecimal插件,如下:
https://github.com/2ndquadrant/fixeddecimal
fixeddecimal的原理很簡單,實際上它是使用int8來存儲的,整數位和小數位是在代碼中固定的:
如果 fixeddecimal_scale 設定為2,則fixeddecimal_multiplier 設定為100,如果 fixeddecimal_scale 設定為3,fixeddecimal_multiplier 設定為1000。
也就是通過整型來存儲,顯示時除以multiplier得到整數部分,取餘得到小數部分。
是以fixeddecimal能存取的值範圍就是int8的範圍除以multiplier。
另外需要注意,編譯fixeddecimal需要用到支援__int128的編譯器,gcc 4.9.3是支援的。是以如果你用的gcc版本比較低的話,需要提前更新好gcc。
http://blog.163.com/digoal@126/blog/static/163877040201601313814429/
下面測試一下fixeddecimal+postgresql 9.5的性能表現,對1億資料進行加減乘除以及聚合的運算,看float8, numeric, fixeddecimal類型的運算結果和速度:
使用auto_explain記錄下對比float8,numeric,fixeddecimal的執行計劃和耗時。
性能對比:

注意上面的測試case,
float8的結果已經不準确了,fixeddecimal使用了預設的scale=2,是以小數位保持2位精度。
numeric則精度更高,顯示的部分沒有顯示全,這是pg内部控制的。
另外需要注意的是,fixeddecimal對于超出精度的部分是做的截斷,不是round, 是以123.555是存的12355而不是12356。