從字段設計、SQL 改寫、索引策略、事務鎖控、架構拆分到大流量應對,匯總 15 條落地可執行的優化法則,附反面教材與驗證方法。
NOT NULL:避免 NULL 判斷開銷、統計函數忽略 NULL、複合索引失效風險。CHAR(2) 存「省份、性別」優於 VARCHAR(20);枚舉值用 ENUM 或 TINYINT。INT UNSIGNED (INET_ATON/INET_NTOA),金額存 DECIMAL 或分為單位 BIGINT。-- 低效:NOT IN 子查詢
DELETE FROM customerinfo WHERE customerid NOT IN (SELECT customerid FROM orderinfo);
-- 高效:LEFT JOIN + IS NULL
DELETE c FROM customerinfo c
LEFT JOIN orderinfo o ON c.customerid = o.customerid
WHERE o.customerid IS NULL;
MySQL 5.6+ 對子查詢優化較好,但 JOIN 穩定性更強,尤其大數據量。
SELECT name FROM nametest
UNION
SELECT username FROM nametest2;
UNION 自動去重,UNION ALL 保留重複、效能更高。
START TRANSACTION;
INSERT INTO customerinfo (name) VALUES ('A');
UPDATE orderinfo SET status=1 WHERE customer_id=LAST_INSERT_ID();
COMMIT;
異常時 ROLLBACK。注意:長事務鎖定資源久,盡量縮短事務範圍。
LOCK TABLES customerinfo READ, orderinfo WRITE;
SELECT customerid FROM customerinfo WHERE id=1;
UPDATE orderinfo SET title='X' WHERE customerid=1;
UNLOCK TABLES;
僅限 MyISAM/MEMORY 或 InnoDB 顯式鎖表場景;InnoDB 行鎖通常無需手動鎖表。
CREATE TABLE customerinfo (customerid INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE orderinfo (
orderid INT, customerid INT,
PRIMARY KEY (customerid, orderid),
FOREIGN KEY (customerid) REFERENCES customerinfo(customerid) ON DELETE CASCADE
) ENGINE=InnoDB;
注意:高併發下外鍵會增加鎖爭用,大廠常在應用層保證完整性、資料庫層不建外鍵。
| 類型 | 建立語法 | 特點 |
|---|---|---|
| 普通 | CREATE INDEX idx_name ON t(col); | 允許重複、NULL |
| 唯一 | CREATE UNIQUE INDEX uk_name ON t(col); | 不允許重複、允許多個 NULL |
| 主鍵 | PRIMARY KEY (col) 建表時指定 | 唯一+非空、聚簇索引 |
| 全文 | CREATE FULLTEXT INDEX ft_name ON t(col); | 5.6+ InnoDB 支援中文分詞需插件 |
-- 惡例:函數導致索引失效
SELECT * FROM orders WHERE YEAR(order_date) < 2008;
-- 良例:範圍查詢走索引
SELECT * FROM orders WHERE order_date < '2008-01-01';
-- 惡例:運算在列上
SELECT * FROM orders WHERE amount/7 < 24;
-- 良例:常數運算移至右側
SELECT * FROM orders WHERE amount < 24*7;
-- 模糊查詢 % 開頭不走索引
SELECT * FROM orders WHERE title LIKE '%good%';
-- 改用全文索引或業務妥協
NOW() 當前日期時間DATE() 日期格式化TIMESTAMP 列 DEFAULT CURRENT_TIMESTAMP 自動寫入mysql_num_rows() 結果集行數 (PHP)MyISAM、InnoDB、Memory、Archive、CSV、Blackhole、Federated、Merge、NDB、RocksDB (MyRocks) 等。生產 99% 用 InnoDB。
key_buffer_size、innodb_buffer_pool_size、query_cache_size (5.7 後查詢快取已廢)。DISTINCT、GROUP BY、多表 JOIN、SELECT *。| 步驟 | 代碼 | 返回類型 |
|---|---|---|
| 連接 | mysql_connect() | resource |
| 選庫 | mysql_select_db() | bool |
| 設編碼 | mysql_query('SET NAMES utf8') | bool |
| 查詢 | mysql_query('SELECT ...') | resource |
| 取行 | mysql_fetch_row() | array |
優化是持續過程:建立基線 → 找瓶頸 (慢查詢、EXPLAIN、SHOW STATUS) → 單點突破 → 驗證回歸 → 迭代。切忌為優化而優化,業務價值優先。