Web 應用性能瓶頸 80% 在數據庫層。MySQL 預設配置僅適合玩具級負載,生產環境必須系統性優化。本文覆蓋 Schema 設計、查詢優化、服務器參數、存儲引擎四大維度。
| 維度 | 標準化 (3NF) | 反範式化 |
|---|---|---|
| 數據冗余 | 無 | 有 |
| 更新成本 | 低(單點更新) | 高(多表同步) |
| 查詢性能 | 需 JOIN,較慢 | 無 JOIN,極快 |
| 適用場景 | OLTP 核心業務 | OLAP/報表/緩存表 |
策略:核心業務堅持 3NF;報表/統計/緩存表適度反範式化;關鍵外鍵列冗余名稱字段避免 JOIN。
TINYINT < SMALLINT < MEDIUMINT < INT < BIGINTUNSIGNED 雙倍範圍CHAR 適合固定長度(MD5、UUID、ISO 代碼)DATE/DATETIME/DECIMAL 原生類型latin1(1 字節),多語言用 utf8mb4(4 字節),避免混用(a,b,c) 支持 a/a,b/a,b,c,不支持 b/c/b,cSELECT a,b FROM t WHERE c=1 → 索引 (c,a,b) 避免回表(a,b) 存在時勿建 (a)INDEX(name(8)) 平衡大小與選擇性ANALYZE TABLE 更新統計信息,OPTIMIZE TABLE 整理碎片(低峰期執行)type(避免 ALL/index)、key、rows、Extra(Using index/where/filesort/temp table)WHERE varchar_col = 123 隱式轉換導致索引失效,必須 '123'long_query_time=1、log_queries_not_using_indexes=ON,配合 pt-query-digest 分析LIMIT 100000, 20 → 延遲關聯:SELECT * FROM t INNER JOIN (SELECT id FROM t LIMIT 100000, 20) tmp USING(id)JOIN 臨時表 或 UNION ALL| 參數 | 建議值 | 說明 |
|---|---|---|
innodb_buffer_pool_size | 物理內存 60-80% | InnoDB 核心緩存,數據+索引+鎖+自適應哈希 |
innodb_log_file_size | 256M-1G | 大檔減少 checkpoint 頻率,提升寫入;過大延長恢復時間 |
innodb_flush_log_at_trx_commit | 1 | 雙 1 配置最高安全;2 性能妥協 |
innodb_flush_method | O_DIRECT | 繞過 OS 雙重緩存,RAID 下效果顯著 |
innodb_file_per_table | ON | 獨立表空間,便於回收空間、遷移、I/O 隔離 |
max_connections | 1000-5000 | 配合連接池,避免 Too many connections |
table_open_cache | 2000-5000 | 減少打開/關閉表開銷 |
query_cache_type | OFF (5.7+) | 高併發寫入場景關閉,唯讀場景可開 |
sort_buffer_size | 2M-8M | 會話級,大排序調大,謹防 OOM |
read_rnd_buffer_size | 1M-4M | 隨機讀緩存,優化 ORDER BY/范圍查詢 |