寫入優化:核心思想
盡量一次性寫入 Data File,減少 Checkpoint 操作,程序端批量提交,減少 IO 衝突。
關鍵參數調整(寫入提升 1000 倍:1000/min → 10000/sec)
| 參數 | 默認 | 調優值 | 作用 |
innodb_flush_log_at_trx_commit | 1 | 0/2 | 0: 1 秒刷盤;2: 提交寫 OS 緩存。犧牲 1 秒數據換吞吐 |
innodb_autoextend_increment | 8M | 128M | 減少表空間自動擴展頻率,避免擴展時全庫阻塞 |
innodb_log_buffer_size | 1M | 16M | 增大 Redo 緩存,減少刷盤頻率 |
innodb_log_file_size | 8M | 128M | 增大 Redo 文件,減少 Checkpoint 觸發 |
⚠️ 修改 innodb_log_file_size 需停庫、刪 ib_logfile*、重啟。
架構層面:獨立表空間 + 分區 + 多盤分佈
# 1. 開啟獨立表空間
innodb_file_per_table = ON
# 2. 大表遷移獨立表空間
ALTER TABLE big_tbl TABLESPACE innodb_file_per_table; -- 5.7+ 或重建表
# 3. 分區(以 uid 為鍵)
ALTER TABLE big_tbl
PARTITION BY HASH(uid) PARTITIONS 16;
# 4. 物理分佈:不同分區掛載不同 RAID/SSD
-- 符號鏈接 datadir/big_tbl#p#p0 → /mnt/ssd1/big_tbl_p0.ibd
讀取優化:三板斧
- SQL 簡化:只選所需列、避免
SELECT *
- 索引覆蓋:
WHERE uid=? + INDEX(uid, col1, col2) 避免回表
- 分區裁剪:查詢條件含分區鍵 → 僅掃描目標分區
實測效果對比
| 階段 | 寫入速度 | 讀取 5K 行更新 |
| 初始 | 1,000 行/分 | 2-3 秒 |
| 參數調優 | 10,000 行/秒 | 2-3 秒(無變化) |
| 分區+多盤 | 持續 10,000 行/秒 | 未顯著提升(索引未命中分區裁剪) |
關鍵教訓
- MySQL 分區**不自動創建分區索引**,需額外在分區鍵上建索引
- 索引與數據同表空間,無法分離管理(不如 Oracle 靈活)
- 讀取瓶頸往往在**索引設計**,而非分區本身
- 參數調優見效快,架構調優見效慢但上限高
生產調優清單
[mysqld]
# 寫入優化
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 64M
innodb_log_file_size = 1G
innodb_autoextend_increment = 128M
innodb_file_per_table = ON
# 讀取優化
innodb_buffer_pool_size = 70% 物理內存
innodb_buffer_pool_instances = 8
# IO 優化
innodb_flush_method = O_DIRECT
innodb_io_capacity = 5000