天天看點

震精 - PostgreSQL 單機3.9 萬億/天(計數器、序列、自增)

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萬億個自增值,你想讓它成為瓶頸都難。