数据库性能实测: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 = QPS
  • sysbench oltp_point_select:每事务 = 1 个 SELECT → TPS = QPS
  • sysbench oltp_read_only:每事务 = 16 个查询 → QPS = TPS × 16

测试结果

线程MySQL TPSPostgreSQL TPSMySQL 优势
10 6,410 5,373 +19%
50 6,502 5,267 +23%
100 6,590 4,753 +39%

关键发现

  1. MySQL 吞吐量更高:各并发级别都领先 20-40%
  2. MySQL 高并发更稳定:并发增加,性能略有提升
  3. 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、全文搜索) 各有千秋,需具体评估

总结

  1. Docker 本身开销可忽略(<5%),桥接网络才是性能杀手
  2. Unix socket 比 TCP 快 23%,优先使用
  3. MySQL 单点查询比 PostgreSQL 快 20-40%,高并发下差距更大
  4. 测试方法很重要,参数错误会得出错误结论

测试日期:2025年12月
测试环境:阿里云 ECS 2核2G,Alibaba Cloud Linux 8
测试工具:sysbench 1.0.20,pgbench (PostgreSQL 13.22)

posted @ 2025-12-08 19:59  猫哥_kaiye  阅读(4)  评论(0)    收藏  举报