前言
在數據庫查詢中,經常用到表關聯,聽到最多的規則是 “小表驅動大表”。那么問題來了
什么是小表驅動大表 ?
為什么要用小表驅動大表 ?
怎么區分那個是驅動表與被驅動表 ?
JOIN 查詢如何選擇驅動表與被驅動表 ?
索引應該建在驅動表還是被驅動表 ?
- 什么是小表驅動大表 ?
小表驅動大表指的是用小的數據集驅動大的數據集。
- 為什么要用小表驅動大表 ?
例如:現有兩個表 A 與 B ,表 A 有 200 條數據,表 B 有 20 萬條數據 ;
按照循環的概念舉個例子
小表驅動大表 > A 驅動表,B 被驅動表
for(200 條){for(20 萬條){...}}
大表驅動小表 > B 驅動表,A 被驅動表
for(20 萬){for(200 條){...}}
總結:
如果小的循環在外層,對於表連接來說就只連接 200 次 ;
如果大的循環在外層,則需要進行 20 萬次表連接,從而浪費資源,增加消耗 ;
綜上:
小表驅動大表的主要目的是通過減少表連接創建的次數,加快查詢速度 。
-
怎么區分那個是驅動表與被驅動表 ?
通過 EXPLAIN 查看 SQL 語句的執行計划可以判斷在誰是驅動表,EXPLAIN 語句分析出來的第一行的表即是驅動表 ; -
JOIN 查詢如何選擇驅動表與被驅動表 ?
在 JOIN 查詢中經常用到的 inner join、left join、right join
問題解答:
1.當使用 left join 時,左表是驅動表,右表是被驅動表 ;
2.當使用 right join 時,右表時驅動表,左表是驅動表 ;
3.當使用 inner join 時,mysql 會選擇數據量比較小的表作為驅動表,大表作為被驅動表 ;
測試結論:
測試環境配置:MYSQL 5.7
數據准備:
創建兩張測試表
大表 user_big_info ,測試數據 400 萬條, 小表 user_small_info ,測試數據 200 萬條 ;
CREATE TABLE `user_small_info` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID', `user_id` varchar(32) NOT NULL COMMENT '用戶唯一標識', `username` varchar(32) NOT NULL DEFAULT '' COMMENT '用戶名', `password` varchar(255) NOT NULL DEFAULT '' COMMENT '密碼', `real_name` varchar(32) NOT NULL DEFAULT '' COMMENT '真實姓名', `phone` varchar(32) NOT NULL DEFAULT '' COMMENT '手機號碼', `remarks` varchar(255) NOT NULL DEFAULT '' COMMENT '備注', `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '狀態 1-啟用 2-禁用 ', `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間', `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間', PRIMARY KEY (`id`), UNIQUE KEY `uniq_user_id` (`user_id`) USING BTREE, KEY `idx_username` (`username`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶表';
LEFT JOIN 測試
小表驅動大表
執行時間:18.141s ,由於使用左連接以小表為主表所以,返回行數:200 萬
執行計划
大表驅動小表
執行時間:25.949s ,由於使用左連接以大表為主表所以,返回行數: 400 萬
執行計划
結論:
當使用 left join 時,左表是驅動表,右表是被驅動表 ; ;
在執行效率上,小表驅動大表優於大表驅動小表 ;
驅動表索引沒有生效,被驅動表索引有效 ;
INNER JOIN 測試
小表驅動大表
執行時間:18.660s ,等值連接返回行數:200 萬
執行計划
大表驅動小表
執行時間:19.060s ,等值連接返回行數:200 萬
執行計划
結論:
當使用 inner join 時,數據庫會選擇數據量比較小的表作為驅動表,大表作為被驅動表 ;
在執行效率上,那個作為主表關系不大,執行效率差距不大 ;
驅動表索引沒有生效,被驅動表索引有效 ;
————————————————
版權聲明:本文為 CSDN 博主「weixin_39634876」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_39634876/article/details/111698250