FOR each row in t1 matching range:
FOR each row in t2 matching ref_key:
FOR each row in t3: -- 驅動表 (最內層)
IF row satisfies join conditions:
SEND to client
EXPLAIN 中的 type=range/ref/ALLMySQL 優化器傾向選擇 **結果集最小的表作為驅動表 (最內層)**,以最小化內層掃描次數。可用 STRAIGHT_JOIN 強制指定連接順序。
FOR each row in t1 matching range:
FOR each row in t2 matching ref_key:
STORE used columns from t1,t2 IN join_buffer
IF buffer_full:
FOR each row in t3:
FOR each (t1,t2) combo IN join_buffer:
IF matches: SEND to client
EMPTY buffer
IF buffer_not_empty:
FOR each row in t3:
FOR each (t1,t2) combo IN join_buffer:
IF matches: SEND to client
join_buffer (內存)若 Buffer 緩存 10 行組合,內層每行與這 10 組比較 → 內層掃描 1 次,而非 10 次。
t3 掃描次數 ≈ (S × C) / join_buffer_size + 1 S = 每組組合大小, C = 組合數量
join_buffer_size 越大 → 掃描次數越少SET join_buffer_size=32M,避免全局過大佔用內存SELECT * 會把所有列塞入 Buffer,劇增 SExtra=Using join buffer (Block Nested Loop) 確認 BNLJ 生效MySQL 僅支援 Nested-Loop 系連接算法。理解 **NLJ → BNLJ** 的演進、join_buffer 的作用、驅動表選擇邏輯,是編寫高效連接查詢、調優大表 JOIN 的核心基礎。期待未來版本引入真正的 Hash Join / Merge Join。