key_buffer_size 是 MyISAM 儲存引擎索引緩衝區的大小控制參數,直接決定索引讀取速度。雖然 InnoDB 已成主流,但 MyISAM 仍廣泛用於內部臨時表、系統表及部分歷史業務表。本文結合官方文檔、實戰案例與監控體系,構建從原理認知到精準調優的完整知識鏈路。
將熱點表索引隔離至專屬緩存,避免冷熱數據擠佔:
-- 1. 創建命名緩存
SET GLOBAL key_buffer_1.key_buffer_size = 8M;
SET GLOBAL key_buffer_2.key_buffer_size = 8M;
-- 2. 綁定表到指定緩存
CACHE INDEX t1, t2 IN key_buffer_1;
-- 3. 預熱載入索引
LOAD INDEX INTO CACHE t1, t2;
適用場景:核心業務表(如用戶表、訂單索引)固定佔用專屬緩存,防止大報表掃描沖刷熱點索引。
mysql> SHOW GLOBAL STATUS LIKE 'Key_read%';
+-------------------+-------------+
| Variable_name | Value |
+-------------------+-------------+
| Key_read_requests | 27813678764 |
| Key_reads | 6798830 |
+-------------------+-------------+
未命中率 = Key_reads / Key_read_requests × 100%
案例:上述數據未命中率 0.0244%,屬良好區間;若目標極致,可擴容至 0.01% 以下。
mysql> SHOW GLOBAL STATUS LIKE 'Key_blocks_u%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Key_blocks_unused | 0 |
| Key_blocks_used | 413543|
+-------------------+-------+
使用率 = Key_blocks_used / (Key_blocks_used + Key_blocks_unused) × 100%
單個 key_buffer_size > 4GB 可能觸發已知 Bug:
破解方案:拆分為多個命名 Key Cache,各自 < 4GB。
key_buffer_size=512M,Key_reads/Key_read_requests ≈ 0.1%。2048M (2GB)。| 現象 | 可能原因 | 調整方向 |
|---|---|---|
Opened_tables 持續快增 | table_cache 過小 | 增大 table_cache |
Key_reads 過大 / 未命中率 > 0.1% | key_buffer_size 不足 | 增大 key_buffer_size |
Handler_read_rnd 過大 | SQL 缺乏索引/全表掃描 | 優化 SQL、補充索引 |
Threads_created 過大 | thread_cache_size 過小 | 增大 thread_cache_size |
Created_tmp_disk_tables 過大 | tmp_table_size/max_heap_table_size 過小 | 增大臨時表記憶體上限 |
key_buffer_size 只服務 MyISAM 索引,InnoDB 走 innodb_buffer_pool_size。Key_reads/Key_read_requests 為北極星,輔以 Key_blocks_used 使用率。優化無終點,唯有在「監控→分析→調整→驗證」的螺旋上升中,讓資料庫始終跑在業務負載的最優曲線上。