详见

https://www.postgresql.org/docs/current/pgbench.html

由于pgbench支持客户端并行,可以开启多个链接进行测试。每个链接有一个唯一的标示:

client_id :

unique number identifying the client session (starts from zero)

或者将client_id作为动态identify的suffix组成,实现不同线程操作不同表的需求。(pgbench暂时还不支持这个功能, 可以参考这里说明 需要修改pgbench代码parseQuery)

upsert,确保不同的会话一定相互不会出现行级锁冲突干扰。

数据ID范围1亿,64个并发操作。确保不同并发操作的ID相互绝对不会重叠

说明:

  1. \set id random(1,100000000)/64+:client_id
  2. random(1,100000000) 返回11亿之间的随机int
  3. /64除以64得到trunc int
  4. +:client_id 加每个线程的number
  5. 得到的值,赋予给id 从而不同的线程绝对不会有重复的id出现

性能杠杠的

  1. pgbench -M prepared -n -r -P 1 -f ./test.sql -c 64 -j 64 -T 120
  2. transaction type: ./test.sql
  3. scaling factor: 1
  4. number of clients: 64
  5. duration: 120 s
  6. number of transactions actually processed: 25803874
  7. latency average = 0.297 ms
  8. latency stddev = 0.251 ms
  9. tps = 215005.904762 (including connections establishing)
  10. tps = 215027.544261 (excluding connections establishing)
  11. statement latencies in milliseconds:
  12. 0.001 \set id random(1,100000000)/64+:client_id
  13. 0.296 insert into t ...........................

如果没有使用client_id,那锁冲突就会比较严重,造成等待影响性能。从25万qps下降到了18万qps。

  1. vi test.sql
  2. \set id random(0,31)
  3. insert into t values (:id, md5(random()::text), now()) on conflict (id) do update set info=excluded.info , crt_time=excluded.crt_time;
  4. transaction type: ./test.sql
  5. scaling factor: 1
  6. query mode: prepared
  7. number of clients: 32
  8. number of threads: 32
  9. duration: 120 s
  10. number of transactions actually processed: 21619627
  11. latency average = 0.177 ms
  12. latency stddev = 0.138 ms
  13. tps = 180162.287114 (including connections establishing)
  14. tps = 180174.521514 (excluding connections establishing)
  15. statement latencies in milliseconds:
  16. 0.177 insert into t values (:id, ............

期待pgbench支持在identify字段中支持变量,而不仅仅是非identify内容中支持变量。

《PostgreSQL 使用 pgbench 测试 sysbench 相关case - pg_oltp_bench》

《PostgreSQL native partition 分区表性能优化之 - 动态SQL+服务端绑定变量》