PHP 專案瓶頸多半在資料庫層。本文從 SQL 寫法、架構設計、索引策略、查詢分析、主從架構到分庫分表,系統梳理 MySQL 優化完整知識體系,助你精準定位並解決效能問題。
ALTER TABLE t AUTO_INCREMENT = N 避免 ID 耗盡。INT(5) ZEROFILL → 00001,前導零顯示需求。DROP INDEX → 載入資料 → ADD INDEX,避免逐行維護索引。mysql -u user -ppass db < file.sql(-p 緊接密碼無空格)。INT > DATE/TIME > ENUM/CHAR > VARCHAR > BLOB/TEXT。INET_ATON() 存 UNSIGNED INT,比 CHAR(15) 省空間且利於範圍查詢。PARTITION BY RANGE/LIST/HASH/KEY,RANGE 最常用(如按時間分區),實現分區裁剪。| 特性 | MyISAM | InnoDB |
|---|---|---|
| 儲存結構 | 三檔 | 單一表空間 (ibdata/ibd) |
| 事務 | 不支援 | 支援 (ACID) |
| 鎖粒度 | 表鎖 | 行鎖 + MVCC |
| 全文索引 | 支援 (不適中文) | 5.6+ 支援 |
| COUNT(*) | 極快 (儲存行數) | 需掃描 |
| 外鍵 | 不支援 | 支援 |
結論:除純讀取、無事務、全文搜尋(需 Sphinx/ES)場景,預設選 InnoDB。
ALTER TABLE t ADD INDEX idx_col(col(n)) 只索引前 n 字元。SELECT COUNT(DISTINCT LEFT(col, n))/COUNT(*) FROM t 測覆蓋率,選接近飽和的 n。極端相同前綴可反轉字串存儲再建索引。OPTIMIZE TABLE t 或 ALTER TABLE t ENGINE=InnoDB 重建。[mysqld]
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=1 -- 秒
分析工具:mysqldumpslow -s t -t 10 slow.log(按時間排序前 10)。| 欄位 | 核心含義 | 優化方向 |
|---|---|---|
| type | 訪問類型:system > const > eq_ref > ref > range > index > ALL | 避免 ALL (全表掃描),爭取 ref/range |
| key | 實際用到的索引 | 為 NULL 則無索引可用 |
| rows | 預估掃描行數 | 越小越好 |
| Extra | Using filesort/where/index | filesort 需優化;Using index 覆蓋索引最佳 |
SET profiling=1;
-- 執行查詢
SHOW PROFILES;
SHOW PROFILE CPU, BLOCK IO FOR QUERY ;
server-id 唯一、log-bin 啟用、GRANT REPLICATION SLAVE、CHANGE MASTER TO ...、START SLAVE。mysql-proxy、Atlas、ProxySQL 等,將 SELECT 路由至 Slave。user_id % 10)。每個優化點都可深入展開,建議建立團隊優化檢查清單,持續迭代。