資料庫效能優化是系統工程,涵蓋設計、SQL、參數、硬體四層次,影響力遞減。本文建立優化知識體系,詳細解析三範式通俗理解、適度冗余原則、SQL 優化標準流程、SHOW STATUS 關鍵指標、慢查詢日誌配置與 EXPLAIN 執行計畫深度解讀。
my.cnf)原則:優先解決高層次問題,事半功倍。
| 範式 | 核心要求 | 通俗理解 |
|---|---|---|
| 1NF | 屬性原子性 | 每欄位不可再分,關聯式資料庫天然滿足 |
| 2NF | 記錄唯一性 | 每行有唯一標識(主鍵),實體唯一 |
| 3NF | 無冗余 | 非主鍵欄位不傳遞依賴主鍵,無衍生欄位 |
反例:單位表 500 行,學生活動 200 萬行。為避免 Join 將單位名冗余到活動表 → 表膨脹 3 倍、I/O 暴增、更新單位名需改 4000 行冗余資料 → 得不償失。
正例:訂單表冗余 total_price(可從明細加總得出) → 查詢訂單總額無需 Join 明細 → 查詢加速、更新僅在訂單建立/修改時同步 → 合理。
結論:冗余應發生在 1 這一方(基數小、更新頻低、查詢頻高)。
SHOW [SESSION|GLOBAL] STATUS LIKE 'Com_%'; — 瞭解 SELECT/INSERT/UPDATE/DELETE 執行頻率比例。EXPLAIN 分析執行計畫。| 指標 | 含義 |
|---|---|
Com_select | 查詢次數 |
Com_insert | 插入次數 |
Com_update | 更新次數 |
Com_delete | 刪除次數 |
Connections | 嘗試連線總數 |
Uptime | 服務運行秒數 |
Slow_queries | 慢查詢次數(預設 >10s) |
SHOW VARIABLES LIKE 'long_query_time'; -- 查看預設 10
SET long_query_time = 2; -- 臨時調整,生產建議 1~2 秒
-- 永久生效需寫入 my.cnf: long_query_time=2
mysqld --log-slow-queries[=file] 或 my.cnf 設 log-slow-queriesmy.cnf 設 slow-query-log=1, slow-query-log-file=...my.cnf 設 slow_query_log=1-- 建表
CREATE TABLE dept(...) ENGINE=MyISAM;
CREATE TABLE emp(...) ENGINE=MyISAM;
CREATE TABLE salgrade(...);
-- 存儲過程產生 400 萬筆測試資料
DELIMITER $$
CREATE FUNCTION rand_string(n INT) RETURNS VARCHAR(255) ...
CREATE PROCEDURE insert_emp(IN start INT, IN max_num INT) ...
CALL insert_emp(100001, 4000000);
-- 子查詢 + 大表掃描,極慢
SELECT * FROM emp WHERE empno = (SELECT empno FROM emp WHERE ename='研發部');
-- Join 有索引則快
SELECT * FROM emp e, dept d WHERE e.empno=100002 AND e.deptno=d.deptno;
EXPLAIN SELECT * FROM emp WHERE ename='JKLOIP'\G
| 欄位 | 含義 | 關鍵值 |
|---|---|---|
| id | SELECT 識別符 | 數字序號 |
| select_type | 查詢類型 | SIMPLE, PRIMARY, SUBQUERY, DEPENDENT SUBQUERY, UNION, UNION RESULT |
| table | 輸出結果表 | 表名/ |
| type | 存取類型(關鍵) | system > const > eq_ref > ref > range > index > ALL |
| possible_keys | 可能用到的索引 | 索引名列表 |
| key | 實際使用索引 | 索引名/NULL |
| key_len | 索引長度 | 位元組數 |
| rows | 預估掃描行數 | 越小越好 |
| Extra | 額外資訊 | Using index, Using where, Using filesort, Using temporary, Impossible WHERE |
>, <, IN, BETWEEN)。Using filesort:需外部排序(ORDER BY 無索引支援)。Using temporary:需建立臨時表(GROUP BY/DISTINCT 無索引)。Using index:覆蓋索引,僅讀索引不回表,極佳。Using where:WHERE 過濾(存取類型非 ALL 時為佳)。建立「設計優先、SQL 為核、參數輔助、硬體兜底」的優化思維模型,配合 SHOW STATUS 基線監控、慢查詢日誌持續收集、EXPLAIN 深度分析,將效能優化從經驗主義轉向數據驅動工程實踐。