-- 全局狀態變量(重點關注)
SHOW GLOBAL STATUS;
-- 關鍵指標解讀
-- Aborted_connects 連接嘗試失敗數
-- Connections 總連接嘗試數
-- Max_used_connections 歷史峰值併發連接數
-- Threads_connected 當前打開連接數
-- Threads_running 當前活躍查詢線程數
-- Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests 緩衝池命中率
-- Created_tmp_disk_tables 磁盤臨時表數(應盡量為 0)
-- Select_scan 全表掃描次數
-- Sort_merge_passes 排序溢寫磁盤次數
| 命令 | 用途 |
|---|---|
SHOW PROCESSLIST | 當前線程列表,排查長事務、鎖等待 |
SHOW ENGINE INNODB STATUS | InnoDB 內部狀態:鎖、事務、死鎖、緩衝池、插入緩衝 |
SHOW TABLE STATUS LIKE 'tbl' | 表統計:行數、數據長度、索引長度、自增值、碎片率 |
SHOW INDEX FROM tbl | 索引詳情:基數、前綴長度、是否唯一 |
SHOW VARIABLES LIKE 'innodb%' | InnoDB 參數快速查閱 |
SHOW CREATE TABLE tbl | 獲取建表 DDL,含分區、外鍵、字符集 |
-- 原始查詢
EXPLAIN SELECT tt.TicketNumber, tt.TimeIn, et.COUNTRY, do.CUSTNAME
FROM tt, et, et AS et_1, do
WHERE tt.SubmitTime IS NULL
AND tt.ActualPC = et.EMPLOYID
AND tt.AssignedPC = et_1.EMPLOYID
AND tt.ClientID = do.CUSTNMBR;
表結構與索引現狀:
| 表 | 列 | 類型 | 索引 |
|---|---|---|---|
| tt | ActualPC | CHAR(10) | 有 |
| tt | AssignedPC | CHAR(10) | 有 |
| tt | ClientID | CHAR(10) | 有 |
| et | EMPLOYID | CHAR(15) PK | 主鍵 |
| do | CUSTNMBR | CHAR(15) PK | 主鍵 |
EXPLAIN 初始輸出(全 ALL,笛卡爾積 450 億行):
table type possible_keys key key_len ref rows Extra
et ALL PRIMARY NULL NULL NULL 74
do ALL PRIMARY NULL NULL NULL 2135
et_1 ALL PRIMARY NULL NULL NULL 74
tt ALL AssignedPC,ClientID,ActualPC NULL NULL NULL 3872 range checked...
tt.ActualPC CHAR(10) vs et.EMPLOYID CHAR(15) → 隱式轉換,索引不可用。tt.ClientID CHAR(10) vs do.CUSTNMBR CHAR(15) → 同理。ALTER TABLE tt MODIFY ActualPC CHAR(15); 等,或修改被引用表列長度(視業務影響)。ALTER TABLE tt ADD INDEX idx_submit_actual (SubmitTime, ActualPC);type 變為 ref/eq_ref,rows 驟降。| 列 | 含義 | 優秀值 | 警惕值 |
|---|---|---|---|
| id | 查詢序號 | — | — |
| select_type | 查詢類型 | SIMPLE, PRIMARY | DEPENDENT SUBQUERY, UNCACHEABLE SUBQUERY |
| table | 訪問表 | — | — |
| partitions | 分區 | — | — |
| type | 訪問類型 | system, const, eq_ref, ref, range, index | ALL (全表掃描) |
| possible_keys | 候選索引 | 有具體名 | NULL |
| key | 實際用索引 | 有具體名 | NULL |
| key_len | 索引鍵長 | 盡可能短 | 過長(含 NULL、可變長) |
| ref | 關聯列/常量 | — | — |
| rows | 預估掃描行 | 越小越好 | 巨大(百萬+) |
| Extra | 額外信息 | Using index, Using where | Using temporary, Using filesort, Range checked for each record |
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 0.5 -- 秒,生產建議 0.5-1
log_queries_not_using_indexes = 1
log_slow_admin_statements = 1
log_slow_slave_statements = 1
pt-query-digest /var/log/mysql/slow.log --limit 20 --filter '$event->{fingerprint} !~ /^SET/'
# 輸出 Top SQL:執行次數、總時間、平均時間、掃描行數、指紋、樣本 SQL
SELECT a, b FROM t WHERE c = 1 → INDEX idx_c_ab (c, a, b),Extra: Using index。INDEX (a, b, c) 支持 a/a,b/a,b,c。WHERE DATE(created) = '2023-01-01' → WHERE created >= '2023-01-01' AND created < '2023-01-02'。ANALYZE TABLE 更新統計信息;OPTIMIZE TABLE 整理碎片(或 ALTER TABLE ... ENGINE=InnoDB)。| 參數 | 建議值 | 說明 |
|---|---|---|
| innodb_buffer_pool_size | 物理內存 60%-80% | 核心緩衝池,數據+索引+鎖+插入緩衝 |
| innodb_log_file_size | 1GB-4GB | Redo log 大小,減少 checkpoint 衝刷 |
| innodb_log_buffer_size | 64MB-256MB | 事務日誌緩衲,大事務調大 |
| innodb_flush_log_at_trx_commit | 1 (安全) / 2 (性能) | 1=每次提交刷盤,2=每秒刷盤 |
| innodb_file_per_table | ON | 獨立表空間,便於回收空間 |
| innodb_read_io_threads / write_io_threads | 4-16 | 後台 IO 線程,SSD 可調大 |
| max_connections | 應用峰值 * 1.5 | 防止 Too many connections |
| query_cache_type / size | OFF / 0 | MySQL 5.7+ 建議關閉,8.0 已移除 |
MySQL 性能優化遵循 「監控 → 發現 → 分析 → 優化 → 驗證」 閉環:
SHOW GLOBAL STATUS、慢查詢日誌 發現瓶頸。EXPLAIN 剖析執行計劃,定位 ALL、Using temporary、filesort、索引失效。Rows_examined、Query_time、Innodb_buffer_pool_reads 等指標下降。工欲善其事,必先利其器。熟練掌握 SHOW/EXPLAIN/慢查詢三板斧,是每個 DBA 與後端工程師的必修課。