MySQL 是強大的開源資料庫,隨著資料驅動應用激增,推動 MySQL 至極限成為常態。本文整理 101 項調優技巧,分類歸納助你系統掌握。部分技巧針對特定環境,但核心思路通用。
一、伺服器硬體與作業系統層面
- 足夠實體記憶體:將整個 InnoDB 檔案載入記憶體,記憶體存取速度遠超硬碟
- 避免 Swap 交換分區:Swap 讀取硬碟,速度極慢
- 使用電池備援 RAM
- 高階 RAID 陣列:推薦 RAID 10 或更高等級
- 避免 RAID 5:校驗機制犧牲寫入效能
- 作業系統與資料分區物理隔離:OS 讀寫干擾資料庫效能
- MySQL 臨時空間、複寫日誌與資料分離不同分區
- 更多磁碟空間 = 更快速度(磁碟控制器可並行操作更多空閒區塊)
- 更快磁碟:SAS 優於 SATA
- 較小硬碟在 RAID 下更快(尋道時間較短)
- 電池備援高速快取 RAID 控制器
- 避免軟體 RAID
- 考慮固態 IO 卡替代磁碟陣列:支援 2GB/s 寫入頻寬
- Linux 設定 swappiness=0:資料庫伺服器無需快取檔案
- 掛載檔案系統加 noatime、nodiratime:避免更新存取時間造成額外寫入
- 使用 XFS 檔案系統:比 ext3 更快、更小,避免雙重緩衝問題
- 調整 XFS 日誌與緩衝參數 追求極致效能
- Linux I/O 排程器用 NOOP 或 DEADLINE:CFQ/ANTICIPATORY 明顯較慢
- 使用 64 位元作業系統:支援更大記憶體位址空間
- 移除未用套件與守護程序:減少資源佔用
- /etc/hosts 寫入客戶端與資料庫主機對應:消除 DNS 查詢延遲
- 切勿強制殺死 MySQL 進程:恐損壞資料與備份程序
- 專機專用:後台服務搶佔 CPU 影響資料庫
二、MySQL 參數配置優化
innodb_flush_method=O_DIRECT:寫入時避免雙重緩衝
- 避免
O_DIRECT 搭配 EXT3:會序列化所有寫入
- 足夠
innodb_buffer_pool_size:載入完整 InnoDB 資料至記憶體
innodb_log_file_size 勿設過大:較小日誌加快崩潰恢復
- 勿混用
innodb_thread_concurrency 與 thread_concurrency:兩者不相容
max_connections 設較小值:過多連線耗盡 RAM 導致鎖死
thread_cache 維持較高值(約 16):減少建立連線開銷
skip-name-resolve:移除 DNS 解析
- 查詢快取雙面刃:重複查詢且資料少變適合啟用;頻繁寫入則拖累效能
- 增大
temp_table_size、max_heap_table_size:防止臨時表寫入磁碟
sort_buffer_size 勿設過高:單連線記憶體乘以連線數易爆 RAM
- 依
key_read_requests/key_reads 比率調整 key_buffer
innodb_flush_log_at_trx_commit=0 提升效能,但犧牲 ACID 與複寫同步;保持 1 需確保磁碟可靠
- 建立測試環境驗證配置,可頻繁重啟不影響生產
三、結構設計優化
- 保持資料庫整潔
- 舊資料歸檔:減少掃描行數
- 適當加索引
- 避免過度索引:比較查詢成本與維護成本
- 壓縮 TEXT/BLOB:節省空間減少磁碟 I/O
- UTF-8/UTF-16 效率低於 latin1
- 節制使用觸發器
- 冗餘資料最小化
- 使用關聯表而非擴展欄位
- 選擇最小足夠資料型別
- BLOB/TEXT 少查詢時分離儲存
- 定期
CHECK TABLE、OPTIMIZE TABLE
- 定期重建 InnoDB 表優化
- 加欄位時先刪索引再加回可更快
- 依需求選擇儲存引擎
- 日誌/稽核表用 Archive 引擎:寫入更高效
- Session 存 Memcached 而非 MySQL:自動過期、避免時空資料堆積
- 可變長字串用 VARCHAR 非 CHAR(UTF-8 除外)
- 結構變更循序漸進:小改動可能大影響
- 開發環境完整模擬生產測試
- 勿隨意修改配置值:可能災難性後果
- 有時少即是多
- 拿不準時用通用配置檔
(下篇將涵蓋查詢優化、索引策略、監控診斷等進階主題)