数据库性能实测:Docker 开销、连接方式、MySQL vs PostgreSQL 全面对比
本文通过多组对照实验,测试 Docker 容器化开销、网络连接方式、数据库版本、MySQL 与 PostgreSQL 性能差异,揭示影响数据库性能的真正因素。
测试背景
网上关于数据库性能的说法众说纷纭:
- "Docker 部署数据库有性能损耗"
- "PostgreSQL 比 MySQL 快"
- "Unix socket 比 TCP 快"
为了搞清楚真相,我在阿里云 ECS 上进行了一系列对照实验。
测试环境:
- 服务器:阿里云 ECS 2核2G
- 系统:Alibaba Cloud Linux 8 (kernel 5.10.134)
- MySQL:8.0.27 / 8.0.44
- PostgreSQL:13.22
- 测试工具:sysbench 1.0.20 / pgbench
一、Docker 桥接网络:性能杀手
初始测试
第一次测试时,我用最简单的方式启动 Docker MySQL:
docker run -d -p 3307:3306 mysql:8.0
结果让我大吃一惊:
| 并发数 | 裸机(Unix socket) | Docker(桥接网络) | 差距 |
|---|---|---|---|
| 50 | 625 QPS | 63 QPS | 10倍 |
| 100 | 667 QPS | 64 QPS | 10倍 |
| 500+ | 正常 | 崩溃 | - |
问题分析
这个对比极不公平:
- 裸机用 Unix socket,Docker 用 TCP
- Docker 使用桥接网络 + NAT 端口转发
- Docker 默认 max_connections=151
桥接网络的 NAT 转发是性能杀手,不是 Docker 本身。
二、Unix Socket vs TCP:23% 的差距
同一台裸机 MySQL,测试不同连接方式:
# Unix socket
sysbench --mysql-socket=/var/lib/mysql/mysql.sock ...
# TCP
sysbench --mysql-host=127.0.0.1 --mysql-port=3306 ...
| 连接方式 | QPS | 差异 |
|---|---|---|
| Unix Socket | 3,476 | 基准 |
| TCP 127.0.0.1 | 2,662 | -23% |
Unix socket 直接通过内核通信,省去 TCP 协议栈开销。
三、Docker vs 裸机:几乎无差异
公平测试条件
- 同版本:MySQL 8.0.44
- 同数据:Docker 挂载裸机数据目录
- 同连接:都用 Unix socket
- 清缓存:
echo 3 > /proc/sys/vm/drop_caches
docker run -d \
-v /var/lib/mysql:/var/lib/mysql \
-v /root/mysql-docker/socket:/var/run/mysqld \
mysql:8.0.44
测试结果
| 线程数 | Docker QPS | 裸机 QPS | 差异 |
|---|---|---|---|
| 50 | 3,567 | 3,454 | +3% |
| 100 | 3,347 | 3,362 | -0.4% |
结论:同等条件下,Docker 和裸机性能几乎完全一致!
四、MySQL 版本:新版不一定更快
| 版本 | 50线程 TPS |
|---|---|
| 8.0.27 | 5,366 |
| 8.0.44 | 5,016 |
8.0.27 比 8.0.44 快约 7%,升级需谨慎。
五、MySQL vs PostgreSQL:MySQL 更快
这是最有争议的话题。为保证公平:
- 相同数据量:10 万行
- 相同测试类型:单点查询(point select)
- 相同并发数
注意 TPS vs QPS:
pgbench -S:每事务 = 1 个 SELECT → TPS = QPSsysbench oltp_point_select:每事务 = 1 个 SELECT → TPS = QPSsysbench oltp_read_only:每事务 = 16 个查询 → QPS = TPS × 16
测试结果
| 线程 | MySQL TPS | PostgreSQL TPS | MySQL 优势 |
|---|---|---|---|
| 10 | 6,410 | 5,373 | +19% |
| 50 | 6,502 | 5,267 | +23% |
| 100 | 6,590 | 4,753 | +39% |
关键发现
- MySQL 吞吐量更高:各并发级别都领先 20-40%
- MySQL 高并发更稳定:并发增加,性能略有提升
- PostgreSQL 高并发下降:100 线程比 10 线程降了 12%
六、踩坑记录:sysbench table-size 参数
现象
早期测试看到 5000+ QPS 的"好成绩",后来发现是假象。
原因
table-size 参数告诉 sysbench 表有多少行,但实际数据可能不匹配:
| table-size 参数 | 实际行数 | 空查询比例 | QPS |
|---|---|---|---|
| 10,000 | 10,000 | 0% | 3,550 |
| 31,898 | 10,000 | 68% | 5,016 |
| 500,000 | 10,000 | 98% | 5,008 |
空查询返回更快,造成虚假高性能。
正确做法
# 先检查实际行数
mysql -e "SELECT COUNT(*) FROM sxsz_db.sbtest1;"
# table-size 必须与实际行数一致
sysbench --table-size=10000 ...
七、性能影响因素排序
| 因素 | 性能影响 | 说明 |
|---|---|---|
| 桥接网络 vs Host/Socket | ~10倍 | NAT 转发开销巨大 |
| MySQL vs PostgreSQL | ~20-40% | MySQL 单点查询更快 |
| Unix socket vs TCP | ~23% | 内核直接通信更快 |
| MySQL 版本 | ~7% | 新版不一定更快 |
| Docker 容器开销 | <5% | 几乎可忽略 |
八、最佳实践
Docker MySQL 高性能配置
docker run -d \
--name mysql \
--network=host \
-v /data/mysql:/var/lib/mysql \
mysql:8.0 \
--max_connections=2000
或使用 Unix socket 挂载:
docker run -d \
--name mysql \
-v /data/mysql:/var/lib/mysql \
-v /var/run/mysqld:/var/run/mysqld \
mysql:8.0
应用连接字符串
// Unix socket(最快)
dsn := "user:pass@unix(/var/run/mysqld/mysqld.sock)/dbname"
// TCP(稍慢,但更通用)
dsn := "user:pass@tcp(127.0.0.1:3306)/dbname"
MySQL vs PostgreSQL 选型建议
| 场景 | 推荐 |
|---|---|
| 高并发简单查询 | MySQL |
| 复杂查询/分析 | PostgreSQL |
| 需要高级特性(JSON、全文搜索) | 各有千秋,需具体评估 |
总结
- Docker 本身开销可忽略(<5%),桥接网络才是性能杀手
- Unix socket 比 TCP 快 23%,优先使用
- MySQL 单点查询比 PostgreSQL 快 20-40%,高并发下差距更大
- 测试方法很重要,参数错误会得出错误结论
测试日期:2025年12月
测试环境:阿里云 ECS 2核2G,Alibaba Cloud Linux 8
测试工具:sysbench 1.0.20,pgbench (PostgreSQL 13.22)


浙公网安备 33010602011771号