萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL 性能調優 101 條黃金法則(硬件、配置、Schema、查詢、備份全維度)

從硬件選型、作業系統調優、MySQL 參數配置、Schema 設計、查詢優化到備份策略,101 條實戰技巧幫你構建高性能、高可用的 MySQL 系統。部分技巧針對特定環境,但底層思路通用。

一、服務器硬件與作業系統調優

  1. 內存足夠大:整個 InnoDB 數據文件能載入內存,內存訪問比磁盤快數量級。
  2. 拒絕 Swap:Swap 讀寫在磁盤,極慢;設置 vm.swappiness=0。
  3. 電池備電 RAID 卡:保證寫緩存掉電不丟失。
  4. RAID 10 首選,避免 RAID 5(校驗開銷大)。
  5. OS 與數據物理隔離:不同磁盤/分區,避免 OS I/O 干擾。
  6. 臨時空間、Relay Log、Binlog 與數據分盤。
  7. 更多、更快的磁盤:SAS > SATA,小容量高轉速盤在 RAID 下更快。
  8. 考慮 NVMe/固態 IO 卡:可達 2GB/s 寫入。
  9. 文件系統選 XFS:比 ext3/4 更快、無雙緩衝問題;掛載加 noatime,nodiratime。
  10. I/O 調度器用 NOOP 或 DEADLINE,避開 CFQ/ANTICIPATORY。
  11. 64 位 OS:支持更大內存寻址。
  12. 精簡系統:移除無用包、守護進程。
  13. /etc/hosts 寫死 IP:消除 DNS 查找延遲。
  14. 嚴禁 kill -9 mysqld:會損壞數據、中斷備份。
  15. 專機專用:避免其他服務搶佔 CPU。

二、MySQL 核心參數配置

  1. innodb_flush_method=O_DIRECT:避免雙緩衝(但不可搭配 EXT3)。
  2. innodb_buffer_pool_size:設為數據總量 70-80%,載入熱數據。
  3. innodb_log_file_size:不宜過大,便於崩潰恢復快速完成。
  4. 勿混用 innodb_thread_concurrency 與 thread_concurrency。
  5. max_connections:設較小值,防連接風暴耗盡內存。
  6. thread_cache_size ≈ 16:減少線程創建開銷。
  7. skip-name-resolve:跳過 DNS 解析。
  8. 查詢緩存:只適用「讀多寫少、數據變化少」場景,否則弊大於利。
  9. tmp_table_size/max_heap_table_size:加大防止臨時表落盤。
  10. sort_buffer_size:勿設過大,否則併發時內存暴漲。
  11. key_buffer_size:參考 Key_read_requests / Key_reads 比率調整。
  12. innodb_flush_log_at_trx_commit=0 提升性能,=1 保數據不丟、主從不延遲,二擇一。
  13. 擁有可重啟的測試環境,驗證配置變更。

三、Schema 設計優化

  1. 保持數據庫整潔,定期歸檔冷數據。
  2. 合理加索引,但切勿過度索引(寫入開銷、優化器誤判)。
  3. 壓縮 TEXT/BLOB 字段,節省空間減 I/O。
  4. UTF8/UTF16 效率低於 latin1,非多語言場景慎用。
  5. 謹慎用觸發器,增加寫入延遲。
  6. 冗余數據最小化,規範化優先。
  7. 用關聯表代替寬表擴展列。
  8. 選最小足夠的數據類型(如 TINYINT 代替 INT)。
  9. 大字段(BLOB/TEXT)拆分到獨立表,主表保留高頻列。
  10. 定期 OPTIMIZE TABLE / ANALYZE TABLE。
  11. InnoDB 表定期重建(ALTER TABLE ... ENGINE=InnoDB)消除碎片。
  12. 加列時可先 Drop Index 再 Add Index,加速 DDL。
  13. 按業務選存儲引擎:日誌/審計用 Archive 引擎。
  14. Session 數據放 Memcached/Redis,勿存 MySQL。
  15. 變長字符串用 VARCHAR,定長用 CHAR(UTF8 除外)。
  16. Schema 變更小步快跑,先在開發環境驗證生產負載。
  17. 配置文件「少即是多」,有疑問用通用模板。

四、查詢優化實戰

  1. 開啟 slow_query_log,長期收集慢查詢。
  2. 用 EXPLAIN 看執行計劃,判斷索引命中、掃描行數。
  3. 持續基準測試,性能會隨數據量變化而退化。
  4. 避免 COUNT(*) 全表掃描鎖表(InnoDB 無此問題,但 MyISAM 有)。
  5. 保持查詢語句一致,利用 Query Cache(若開啟)。
  6. GROUP BY 代替 DISTINCT(某些版本更優)。
  7. WHERE/GROUP BY/ORDER BY 列加索引。
  8. 索引保持簡單,避免多索引包含同一列。
  9. 優化器選錯索引時用 USE INDEX 強制指定。
  10. 啟用 SQL_MODE=STRICT 暴露數據質量問題。
  11. 小基數列 UNION 用 LIMIT 代替 OR。
  12. INSERT ... ON DUPLICATE KEY UPDATE / INSERT IGNORE 代替「先查後更新」。
  13. 不用 MAX(),用索引列 + ORDER BY ... LIMIT 1。
  14. 杜絕 ORDER BY RAND()。
  15. LIMIT M,N 深分頁性能差,慎用或改用游標/延遲關聯。
  16. 子查詢改 UNION 或 JOIN。
  17. 更新用 LOCK IN SHARE MODE 降低鎖衝突。
  18. 重啟後「預熱」數據(SELECT ... FORCE INDEX 掃熱表)。
  19. 清空表用 TRUNCATE / DROP+CREATE,比 DELETE 快得多。
  20. 只 SELECT 需要的列,SELECT * 消耗大。
  21. 考慮持久連接(連接池),減少握手開銷。
  22. 壓測時模擬真實併發,單查詢可能影響整體吞吐。
  23. 高負載時 SHOW PROCESSLIST 定位阻塞查詢。
  24. 可疑查詢在鏡像數據上驗證,勿直接上線。

五、備份策略最佳實踐

  1. 從從庫備份,不影響主庫性能。
  2. 備份期間 STOP SLAVE,避免外鍵/依賴導致不一致。
  3. 冷備份:STOP MYSQL 後拷貝數據文件,最快、最一致。
  4. mysqldump 邏輯備份時同步備份 Binlog,保證增量恢復點連續。
  5. 不信任 LVM 快照:極易產生數據不一致,後患無窮。
  6. 按表導出,便於單表恢復。
  7. mysqldump --opt(含快速插入、鎖表等優化)。
  8. 導入前 CHECK TABLE / OPTIMIZE TABLE。
  9. 導入時臨時關閉 foreign_key_checks=0、unique_checks=0 加速。
  10. 每次備份後統計庫/表/索引大小,監控增長趨勢。
  11. 腳本自動監控主從報錯、延遲。
  12. 定期備份,定期演練恢復(未測試的備份 = 沒備份)。

六、最後一條:監控

部署 MySQL 監控系統(如 Prometheus + Grafana、Percona PMM、或文中提到的 Monitis),全鏈路可觀測:QPS、延遲、連接數、InnoDB 緩存命中率、主從延遲、磁盤 I/O、慢查詢趨勢…… 監控是性能優化的眼睛。

copyright © 萬盛學電腦網 all rights reserved