EXPLAIN 分析 SQL 效能。-- 當 WHERE 篩選後行數較少時,用總數減去反向篩選更快 SELECT (SELECT COUNT(*) FROM world.city) - COUNT(*) FROM world.city WHERE id <= 5;
float vs int、char vs varchar、binary vs varbinary 不相容會阻礙優化器。
-- 錯誤:導致全表掃描 WHERE F1/2 = 100 -- 正確: WHERE F1 = 100*2
導致無法使用索引,改用 EXISTS 替代 IN。
字串比較需逐字元,數值單次比較即完成,效能與儲存雙贏。
-- 低效 WHERE (SELECT COUNT(*) FROM T2 WHERE T2.C2=T1.C2) > 0 -- 高效 WHERE EXISTS (SELECT * FROM T2 WHERE T2.C2=T1.C2)
導致表鎖定,阻塞其他連線。
SELECT * FROM T1 (INDEX = IX_ProcessID) WHERE nextprocess=1 AND processid IN (8,32,45);
-- 原查詢強迫順序掃描 SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008 -- 改用 UNION 走索引路徑 SELECT * FROM orders WHERE customer_num=104 AND order_num>1001 UNION SELECT * FROM orders WHERE order_num=1008
WHERE name LIKE '%L%' -- 全表掃描 WHERE name LIKE 'L%' -- 可用索引
UNION ALL 不執行 DISTINCT 排序,大幅降低資源消耗。已知無重複或不在意重複時首選。
-- 低效 SELECT film_id, description FROM film ORDER BY title LIMIT 50, 5; -- 高效:覆蓋索引偏移後再 JOIN 回表 SELECT f.film_id, f.description FROM film f INNER JOIN (SELECT film_id FROM film ORDER BY title LIMIT 50, 5) tmp USING (film_id);
INSERT INTO person(name,age) VALUES('xboy',14),('xgirl',15),('nia',19);
| SQL 模式 | 建議索引 |
|---|---|
ORDER BY sort LIMIT ... | INDEX(sort) |
WHERE colX=val ORDER BY sort LIMIT ... | INDEX(colX, sort) 聯合索引 |
WHERE colX IN (...) ORDER BY sort LIMIT ... | IN 多值導致 filesort,暫無完美方案 |
WHERE uid=1 ORDER BY x,y LIMIT ... | INDEX(uid, x, y) (非直覺的 (x,y,uid) 效果較差) |
優化無終點,配合 EXPLAIN、慢查詢日誌、performance_schema 持續觀測調整。