這篇博文講述如何優化內循環的次數。內循環的次數受驅動表的記錄數所影響,驅動表記錄數越多,內循環就越多,鏈接效率就越低下,因此儘可能用小表驅動大表。先插入測試數據。html
CREATE TABLE t1 ( id INT PRIMARY KEY AUTO_INCREMENT, type INT ); SELECT COUNT(*) FROM t1; +----------+ | COUNT(*) | +----------+ | 10000 | +----------+ CREATE TABLE t2 ( id INT PRIMARY KEY AUTO_INCREMENT, type INT ); SELECT COUNT(*) FROM t2; +----------+ | COUNT(*) | +----------+ | 100 | +----------+
實際業務場景中,左鏈接、右鏈接能夠根據業務需求認定誰是驅動表,誰是被驅動表。可是內鏈接不一樣,根據嵌套循環算法的思想,t1內鏈接t2和t2內鏈接t1所得結果集是相同的。那麼究竟是誰鏈接誰呢?謹記一句話便可,小表驅動大表能夠減少內循環的次數。下面用 STRAIGHT_JOIN強制左錶鏈接右表。By the way,STRIGHT_JOIN比較冷門,在這裏解釋下,其做用至關於內鏈接,不過強制規定了左表驅動右邊。詳情看這MySQL的JOIN(一):用法mysql
EXPLAIN SELECT * FROM t1 STRAIGHT_JOIN t2 ON t1.type=t2.type; +----+-------+------+------+-------+----------------------------------------------------+ | id | table | type | key | rows | Extra | +----+-------+------+------+-------+----------------------------------------------------+ | 1 | t1 | ALL | NULL | 10000 | NULL | | 1 | t2 | ALL | NULL | 100 | Using where; Using join buffer (Block Nested Loop) | +----+-------+------+------+-------+----------------------------------------------------+ EXPLAIN SELECT * FROM t2 STRAIGHT_JOIN t1 ON t2.type=t1.type; +----+-------+------+------+-------+----------------------------------------------------+ | id | table | type | key | rows | Extra | +----+-------+------+------+-------+----------------------------------------------------+ | 1 | t2 | ALL | NULL | 100 | NULL | | 1 | t1 | ALL | NULL | 10000 | Using where; Using join buffer (Block Nested Loop) | +----+-------+------+------+-------+----------------------------------------------------+
對於第一條查詢語句,t1是驅動表,其有10000條記錄,內循環也就有10000次,這還得了?
對於第二條查詢語句,t2是驅動表,其有100條記錄,內循環100次,感受不錯,我喜歡!
這些SQL語句的執行時間也說明了,當內鏈接時,務必用小表驅動大表。算法
可是,表的記錄數是會變化的,有沒有一勞永逸的寫法?固然有啦,MySQL自帶的Optimizer會優化內鏈接,優化策略就是上面講的小表驅動大表。因此,之後寫內鏈接不要糾結誰內鏈接誰了,直接讓MySQL去判斷吧。sql
EXPLAIN SELECT * FROM t1 INNER JOIN t2 ON t1.type=t2.type; EXPLAIN SELECT * FROM t2 INNER JOIN t1 ON t1.type=t2.type; EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.type=t2.type; EXPLAIN SELECT * FROM t2 JOIN t1 ON t1.type=t2.type; EXPLAIN SELECT * FROM t1,t2 WHERE t1.type=t2.type; EXPLAIN SELECT * FROM t2,t1 WHERE t1.type=t2.type; +----+-------+------+------+--------+----------------------------------------------------+ | id | table | type | key | rows | Extra | +----+-------+------+------+--------+----------------------------------------------------+ | 1 | t2 | ALL | NULL| 100 | NULL | | 1 | t1 | ALL | NULL | 110428 | Using where; Using join buffer (Block Nested Loop) | +----+-------+------+------+--------+----------------------------------------------------+
上面6條內鏈接SQL,MySQL的Optimizer都會進行優化。oop