CHAR(6) 足夠存郵遞區號,勿用 VARCHAR(255);整數優先 TINYINT/SMALLINT/MEDIUMINT 而非 BIGINT。NOT NULL,避免 NULL 判斷開銷。ENUM,內部以整數儲存,比較極快。反例:
DELETE FROM customerinfo WHERE CustomerID NOT IN (SELECT CustomerID FROM salesinfo);
優化:
DELETE c FROM customerinfo c
LEFT JOIN salesinfo s ON c.CustomerID = s.CustomerID
WHERE s.CustomerID IS NULL;
JOIN 避免建立臨時表,配合索引效能提升數倍。
SELECT Name, Phone FROM client
UNION ALL
SELECT Name, BirthDate FROM author
UNION ALL
SELECT Name, Supplier FROM product;
UNION 自動去重(較慢);UNION ALL 保留重複(極快),業務允許時優先用 ALL。START TRANSACTION;
INSERT INTO orders ...;
UPDATE inventory SET qty = qty - 1 WHERE id = 1;
COMMIT; -- 或 ROLLBACK;
LOCK TABLES inventory WRITE;
SELECT qty FROM inventory WHERE item='book';
UPDATE inventory SET qty=11 WHERE item='book';
UNLOCK TABLES;
適用於簡單邏輯、極高併發場景,避免交易開銷。注意:鎖定期間阻塞其他讀寫,慎用。
CREATE TABLE orders (
id INT PRIMARY KEY,
customer_id INT,
FOREIGN KEY (customer_id) REFERENCES customers(id) ON DELETE CASCADE
) ENGINE=InnoDB;
InnoDB 引擎。ON DELETE CASCADE 自動級聯刪除,防孤兒資料。VARCHAR(255) 用 INDEX(name(10))。WHERE YEAR(date_col) = 2023 → WHERE date_col >= '2023-01-01' AND date_col < '2024-01-01'。| 低效寫法 | 高效重寫 | 原理 |
|---|---|---|
WHERE amount/7 < 24 | WHERE amount < 24*7 | 避免欄位運算,索引失效 |
WHERE name LIKE '%keyword%' | WHERE name >= 'keyword' AND name < 'keyworl' | 前導萬用字元無法用索引 |
SELECT * FROM t WHERE a=1 OR b=2 | SELECT * FROM t WHERE a=1 UNION SELECT * FROM t WHERE b=2 | OR 往往導致全表掃描 |
| 隱含型別轉換 | 字串比字串、數字比數字 | 轉換導致索引失效 |
優化是系統工程:硬體 → 系統 → 架構 → SQL → 索引。定期 EXPLAIN、SHOW STATUS、pt-query-digest 分析慢查詢,持續迭代。