本文精選自 Monitis 經典「101 Tips for MySQL Tuning and Optimization」,結合 MySQL 5.7/8.0 現代特性重構分類,去除過時建議,補充生產實踐精華,形成可落地的調優清單。
innodb_buffer_pool_size ≥ 熱數據量 (含索引),目標命中率 > 99%。vm.swappiness=1,或 swapoff -a。Swap 觸發 = 性能雪崩。echo never > /sys/kernel/mm/transparent_hugepage/enabled,防止內存分配延遲抖動。net.core.somaxconn=65535, net.ipv4.tcp_max_syn_backlog=65535, 關閉 DNS 反解 (skip_name_resolve=ON)。chronyd,時間漂移導致 Binlog/GTID/審計混亂。innodb_buffer_pool_size = 物理內存 60-75% (專機)。innodb_buffer_pool_instances = 8 (或 1GB/實例),減少互斥鎖爭用。innodb_log_file_size = 1-4GB,innodb_log_files_in_group=2,大 Redo Log 減少 Checkpoint 衝刷。innodb_flush_log_at_trx_commit = 1 (主庫) / 2 (從庫)。innodb_flush_method = O_DIRECT (配合 XFS/ext4),避免雙緩衝。innodb_io_capacity = 2000 (SATA SSD) / 5000+ (NVMe),innodb_io_capacity_max = 2x。innodb_read_io_threads = 8, innodb_write_io_threads = 8 (高併發可 16/32)。innodb_thread_concurrency = 0 (無限制,現代版本自適應優於手動限制)。max_connections = 2000-5000,thread_cache_size = 100,back_log = 1024。table_open_cache = 4000, table_definition_cache = 2000 (監控 Opened_tables 調整)。query_cache_type = OFF, query_cache_size = 0 (8.0 已移除 QC,5.7 必關,寫入失效開銷極大)。tmp_table_size = 64M, max_heap_table_size = 64M,防止內部臨時表落盤。sort_buffer_size = 2M, join_buffer_size = 2M,**會話級**,不可設過大 (併發 × 大小 = OOM 風險)。binlog_format = ROW, binlog_row_image = FULL, sync_binlog = 1 (主庫),expire_logs_days = 7 (或 binlog_expire_logs_seconds 8.0)。gtid_mode = ON, enforce_gtid_consistency = ON (主從高可用基石)。sql_mode = "STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO"。skip_name_resolve = ON (禁用 DNS 反解)。explicit_defaults_for_timestamp = ON (5.6+ 默認 ON)。INT 而非 BIGINT、CHAR 定長代碼、DECIMAL 金額、DATETIME(3) 毫秒、ENUM 低基數狀態 (慎用,修改結構鎖表)。pt-duplicate-key-checker 定期掃描。pt-online-schema-change / gh-ost,零鎖表變更結構。ANALYZE TABLE 定期/自動 (8.0 innodb_stats_persistent),防止執行計劃劣化。long_query_time=1, log_queries_not_using_indexes=OFF, log_slow_admin_statements=OFF。type (system/const/eq_ref/ref/range/index/all)、key、rows、Extra (Using index/where/temporary/filesort)。SELECT *:只取需要列,減少 I/O、網絡、緩存壓力,利於覆蓋索引。COUNT(*) 陷阱:InnoDB 無觸發器/外鍵時 COUNT(*) 掃描聚簇索引,大表極慢。用計數表/Redis/近似值 (SHOW TABLE STATUS)。LIMIT M, N 深分頁優化:子查詢回表 / 遞增 ID 範圍 / 游標分頁 (見專題文章)。OR 改 UNION ALL:OR 導致索引失效,UNION ALL 分別走索引再合併。WHERE varchar_col = 123 導致全表掃描,應用層/ORM 必須保證類型一致。WHERE dt >= '2023-01-01' AND dt < '2023-02-01' 而非 BETWEEN (含邊界歧義) 或函數 DATE(dt)。STOP SLAVE SQL_THREAD 靜默備份 (邏輯/物理),備份後 START SLAVE。openssl enc -aes-256-gcm 加密存儲,sha256sum 校驗傳輸完整性。SET FOREIGN_KEY_CHECKS=0; SET UNIQUE_CHECKS=0; 加速恢復。Seconds_Behind_Master / Replica_Lag (8.0),告警閾值 30s/300s。Prometheus + mysqld_exporter + Grafana。調優無終點,只有在特定業務、數據量、硬體、版本下的「當前最優解」。建立**監控基線 → 發現瓶頸 → 理論分析 → 受控變更 → 效果驗證 → 固化基線**的閉環流程,比背誦 101 條法則更有價值。願你的 MySQL 穩如磐石,快如閃電。