CHAR(6) 而非 CHAR(255) 或 VARCHARMEDIUMINT 而非 BIGINTNOT NULL,避免 NULL 比較開銷ENUM,內部以數值處理,速度遠快於字串MySQL 4.1+ 支援子查詢,但 JOIN 效率通常更高(避免建立暫存表)。
-- 子查詢:找無訂單客戶
SELECT * FROM customerinfo
WHERE CustomerID NOT IN (SELECT CustomerID FROM salesinfo);
-- JOIN 改寫(配合 salesinfo.CustomerID 索引更快)
SELECT * FROM customerinfo
LEFT JOIN salesinfo ON customerinfo.CustomerID = salesinfo.CustomerID
WHERE salesinfo.CustomerID IS NULL;
MySQL 4.0+ 支援 UNION 合併多個 SELECT,會話結束自動清理暫存表。
SELECT Name, Phone FROM client
UNION
SELECT Name, BirthDate FROM author
UNION
SELECT Name, Supplier FROM product;
注意:所有 SELECT 欄位數必須相同。
BEGIN;
INSERT INTO salesinfo SET CustomerID=14;
UPDATE inventory SET Quantity=11 WHERE item='book';
COMMIT;
ROLLBACK),維護資料完整性大型系統交易鎖定全表影響並發,可用表鎖定細粒度控制:
LOCK TABLE inventory WRITE;
SELECT Quantity FROM inventory WHERE Item='book';
-- 計算後
UPDATE inventory SET Quantity=11 WHERE Item='book';
UNLOCK TABLES;
WRITE 鎖防止其他寫入,讀取仍可進行(視隔離等級)。
CREATE TABLE customerinfo (
CustomerID INT NOT NULL PRIMARY KEY
) ENGINE=INNODB;
CREATE TABLE salesinfo (
SalesID INT NOT NULL,
CustomerID INT NOT NULL,
PRIMARY KEY (CustomerID, SalesID),
FOREIGN KEY (CustomerID) REFERENCES customerinfo(CustomerID)
ON DELETE CASCADE
) ENGINE=INNODB;
ON DELETE CASCADE 級聯刪除相關記錄ENGINE=INNODB)JOIN、WHERE、ORDER BY 使用的欄位FULLTEXT),僅限 MyISAM| 原則 | 錯誤寫法 | 正確寫法 |
|---|---|---|
| 同類型比較 | INT 欄位比 BIGINT | 同類型欄位比較 |
| 索引欄位避免函數運算 | WHERE YEAR(date) < 2001 | WHERE date < '2001-01-01' |
| 數值運算移到右側 | WHERE amount/7 < 24 | WHERE amount < 24*7 |
| 避免 LIKE 導掃全表 | WHERE name LIKE 'MySQL%' | WHERE name >= 'MySQL' AND name < 'MySQM' |
| 避免隱含型別轉換 | 字串比數值 | 明確轉型或同型別比較 |