postgresql , 計數器 , 序列 , 自增值
資料庫中,自增序列是常見的需求,例如計數,主鍵,唯一值,或者自動生成的流水号等等。
是以序列這個功能就應運而生,序列的功能在很多商業資料庫中都支援需求,postgresql當然也支援,而且更好用。
在postgresql中可以建立多個序列,設定序列的起始值,步長,緩存大小,是否輪回等。
序列的應用場景
1. 作為字段預設值,default nextval('序列名');
2. 作為繼承表的分布鍵
例如某個表有64個繼承表,為了區分每個繼承表的資料,可以将繼承表的主鍵都按64取模,得到的結果不同來區分,使用步長很好的解決這個問題。
3. 作為計數器
4. 其他
那麼postgresql序列的性能怎樣呢?
<a href="http://thebuild.com/blog/2015/10/30/dont-assume-postgresql-is-slow/">http://thebuild.com/blog/2015/10/30/dont-assume-postgresql-is-slow/</a>
這個是某位網友的測試,我接下來會在某個32核的機器上測試一下,序列值的生成性能将達到每秒4.5千萬。
使用unix socket連接配接,廁所12種場景,每次取多條時,統一為每次取10萬條。
1. 單個序列(nocache),1個用戶端,每個用戶端,每次取一條
瓶頸
2. 單個序列(nocache),1個用戶端,每個用戶端,每次取多條
3. 單個序列(cache),1個用戶端,每個用戶端,每次取一條
4. 單個序列(cache),1個用戶端,每個用戶端,每次取多條
5. 單個序列(nocache),64個用戶端,每個用戶端,每次取一條
6. 多個序列(nocache),64個用戶端,每個用戶端,每次取一條
7. 單個序列(nocache),64個用戶端,每個用戶端,每次取多條
8. 多個序列(nocache),64個用戶端,每個用戶端,每次取多條
9. 單個序列(cache),64個用戶端,每個用戶端,每次取一條
10. 多個序列(cache),64個用戶端,每個用戶端,每次取一條
11. 單個序列(cache),64個用戶端,每個用戶端,每次取多條
12. 多個序列(cache),64個用戶端,每個用戶端,每次取多條
如果需要較為正确的perf診斷,pg的編譯參數要改一下。
<a href="https://github.com/digoal/blog/blob/master/201611/20161129_01.md">《postgresql 源碼性能診斷(perf profiling)指南》</a>
1. 序列的cache是會話層級的,例如一次cache 100個序列值,那麼一次會消耗100,如果會話退出,這100個沒有被用完的序列值也會被消耗掉。
cache的好處是減少鎖沖突。
如果你不能用cache,那麼可以用多個序列來解決鎖沖突的問題。
如果需要并軌,隻需要将多個序列的步長設為一樣,同時起始值錯開即可并軌。
2. 單個序列值,并發批量取序列值,如何提升性能?
設定cache
3. 并發單步取序列值,不允許cache的情況下,如何提升性能?
使用多個序列,每個會話對應一個序列,多個序列要求步長一緻,起始值不一緻即可。
4. 從上面的測試情況來看,理論上多個序列的性能應該更好,但是測試使用了<code>||</code>來拼接出序列名,帶來了額外的開銷,是以性能并未展現有些。
以單序列,批量并行取序列值的最好成績來估算,每秒生成4550萬自增值,那麼一天可以生成3.9萬億個自增值,你想讓它成為瓶頸都難。