CHAR(6) 存郵編優於 VARCHAR(255);固定長度列用 CHAR。TINYINT(1B) > SMALLINT(2B) > MEDIUMINT(3B) > INT(4B) > BIGINT(8B)。1600 萬行表用 MEDIUMINT 自增 ID 省 10MB+。NOT NULL 默認加上:避免 NULL 比較開銷,節省位圖空間。ENUM('male','female') 視為數值處理,比 VARCHAR 快,僅 1-2 字節。
# 子查詢(建立臨時表,無索引)
SELECT * FROM customerinfo
WHERE CustomerID NOT IN (SELECT CustomerID FROM salesinfo);
# LEFT JOIN(利用 salesinfo.CustomerID 索引,無臨時表)
SELECT c.* FROM customerinfo c
LEFT JOIN salesinfo s ON c.CustomerID = s.CustomerID
WHERE s.CustomerID IS NULL;
原理:MySQL 子查詢物化到無索引臨時表;JOIN 可直接走索引,避免臨時表開銷。
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;
適用場景:單表操作、低衝突、極高併發、事務鎖開銷過大。風險:手動管理鎖範圍,死鎖/死循環風險自負。
CREATE TABLE customerinfo (CustomerID INT PRIMARY KEY) ENGINE=InnoDB;
CREATE TABLE salesinfo (
SalesID INT, CustomerID INT,
PRIMARY KEY (CustomerID, SalesID),
FOREIGN KEY (CustomerID) REFERENCES customerinfo(CustomerID) ON DELETE CASCADE
) ENGINE=InnoDB;
關鍵:ON DELETE CASCADE 級聯刪除;必須用 InnoDB(MyISAM 不支持外鍵)。
JOIN、WHERE、ORDER BY 涉及的列FULLTEXT 僅支持 MyISAM (5.6+ InnoDB 支持),大數據量先導數據後建索引極快,先建索引再導數據極慢| 反模式 | 優化模式 | 原理 |
|---|---|---|
列上用函數:WHERE YEAR(date) < 2001 | 範圍查詢:WHERE date < '2001-01-01' | 函數導致索引失效 |
計算列:WHERE amount/7 < 24 | 移項常數:WHERE amount < 24*7 | 同理,列參與運算索引失效 |
前導模糊:WHERE name LIKE '%MySQL%' | 範圍等價:WHERE name >= 'MySQL' AND name < 'MySQM' | 前導通配符不可用索引,範圍查詢可用 |
隱式類型轉換:WHERE varchar_col = 123 | 顯式轉換:WHERE varchar_col = '123' | 轉換發生在列上導致索引失效 |
優化層級由高到低:架構分庫分表 > SQL/索引優化 > 參數調優 > 硬件升級。八大法則聚焦 SQL/索引/Schema 層,收益最大、成本最低,請優先落地。