强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

PostgreSQL 完全指南 / 20 - 性能测试

第 20 章 · 性能测试

本章介绍 pgbench、压测方法论和连接池对比测试。


20.1 pgbench(内置压测工具)

# 初始化测试数据
pgbench -i -s 50 mydb  # -s 50 表示 50 倍缩放因子(约 500 万行)

# 标准测试(SELECT、UPDATE、INSERT)
pgbench -c 10 -j 4 -T 60 mydb
# -c 10: 10 个并发客户端
# -j 4: 4 个工作线程
# -T 60: 运行 60 秒

# 只读测试
pgbench -c 10 -T 60 -S mydb

# 自定义脚本
cat > my_script.sql << 'EOF'
\set aid random(1, 100000 * :scale)
\set bid random(1, 1 * :scale)
\set tid random(1, 10 * :scale)
\set delta random(-5000, 5000)
BEGIN;
UPDATE pgbench_accounts SET balance = balance + :delta WHERE aid = :aid;
SELECT balance FROM pgbench_accounts WHERE aid = :aid;
UPDATE pgbench_tellers SET balance = balance + :delta WHERE tid = :tid;
UPDATE pgbench_branches SET balance = balance + :delta WHERE bid = :bid;
INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
END;
EOF

pgbench -c 20 -j 4 -T 120 -f my_script.sql mydb

pgbench 输出解读

transaction type: <builtin: TPC-B (sort of)>
scaling factor: 50
query mode: simple
number of clients: 10
number of threads: 4
duration: 60 s
number of transactions actually processed: 12345
latency average = 4.860 ms
latency stddev = 2.340 ms
initial connection time = 15.234 ms
tps = 2058.432 (without initial connection time)
指标含义关注点
tps每秒事务数越高越好
latency average平均延迟越低越好
latency stddev延迟标准差越小越稳定
initial connection time连接建立时间评估连接池效果

20.2 sysbench(通用压测工具)

# 安装
sudo apt install sysbench

# OLTP 读写测试
sysbench oltp_read_write \
  --pgsql-host=127.0.0.1 \
  --pgsql-port=5432 \
  --pgsql-user=postgres \
  --pgsql-password=password \
  --pgsql-db=mydb \
  --db-driver=pgsql \
  --tables=10 \
  --table-size=100000 \
  --threads=16 \
  --time=300 \
  --report-interval=10 \
  run

# 纯读测试
sysbench oltp_read_only ... run

# 纯写测试
sysbench oltp_write_only ... run

# 准备数据
sysbench oltp_read_write ... prepare

# 清理
sysbench oltp_read_write ... cleanup

20.3 压测方法论

压测流程

1. 明确目标
   ├── 吞吐量(TPS/QPS)目标
   ├── 延迟目标(P99 < 100ms)
   └── 并发用户数

2. 环境准备
   ├── 使用生产相似的硬件/配置
   ├── 使用生产规模的数据量
   └── 确保网络/存储一致

3. 预热(Warmup)
   └── 先运行 5-10 分钟让缓存预热

4. 阶梯测试
   ├── 10 并发 → 稳定后记录 TPS
   ├── 50 并发 → 稳定后记录
   ├── 100 并发 → 稳定后记录
   └── 找到拐点(性能下降的并发数)

5. 持续压力测试
   └── 在目标并发下运行 30 分钟以上

6. 分析结果
   ├── TPS 趋势
   ├── 延迟分布(P50/P95/P99)
   ├── 资源使用(CPU/内存/磁盘IO)
   └── 瓶颈分析

关键指标

指标说明工具
TPS每秒事务数pgbench/sysbench
QPS每秒查询数pgbench
P50/P95/P99 延迟百分位延迟pgbench/sysbench
CPU 使用率服务器 CPUtop/htop/iostat
内存使用Shared Buffers 命中率pg_stat_database
磁盘 IOPS读写 IOPSiostat
连接数活跃/空闲连接pg_stat_activity

20.4 连接池对比测试

-- 创建测试场景:不同连接池模式的对比
-- 测试脚本:逐步增加并发

-- 直连(无连接池)
pgbench -c 50 -T 60 -h 127.0.0.1 -p 5432 mydb

-- PgBouncer session 模式
pgbench -c 50 -T 60 -h 127.0.0.1 -p 6432 mydb

-- PgBouncer transaction 模式
pgbench -c 50 -T 60 -h 127.0.0.1 -p 6433 mydb
配置优势劣势
无连接池简单连接数受限,fork 开销大
session 模式会话级功能完整复用率低
transaction 模式最高复用率不支持 LISTEN/NOTIFY
statement 模式极高复用率不支持多语句事务

20.5 性能优化前后对比

-- 优化前
EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 12345;
-- Seq Scan on orders (cost=0.00..125000.00 rows=50 width=56)
-- Execution Time: 850.000 ms

-- 创建索引后
CREATE INDEX idx_orders_customer ON orders (customer_id);
EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 12345;
-- Index Scan using idx_orders_customer on orders (cost=0.43..12.50 rows=50 width=56)
-- Execution Time: 0.500 ms

业务场景

场景压测方法
新系统上线pgbench 标准测试 + 自定义脚本
版本升级验证优化前后 TPS/延迟对比
容量规划阶梯测试找拐点
连接池选型不同并发下的 TPS 对比

扩展阅读