mysql leftjoin 大表在外_小表驅動大表


前言
在數據庫查詢中,經常用到表關聯,聽到最多的規則是 “小表驅動大表”。那么問題來了

什么是小表驅動大表 ?

為什么要用小表驅動大表 ?

怎么區分那個是驅動表與被驅動表 ?

JOIN 查詢如何選擇驅動表與被驅動表 ?

索引應該建在驅動表還是被驅動表 ?

  1. 什么是小表驅動大表 ?

小表驅動大表指的是用小的數據集驅動大的數據集。

  1. 為什么要用小表驅動大表 ?
    例如:現有兩個表 A 與 B ,表 A 有 200 條數據,表 B 有 20 萬條數據 ;
    按照循環的概念舉個例子

小表驅動大表 > A 驅動表,B 被驅動表

for(200 條){for(20 萬條){...}}
大表驅動小表 > B 驅動表,A 被驅動表

for(20 萬){for(200 條){...}}
總結:

如果小的循環在外層,對於表連接來說就只連接 200 次 ;

如果大的循環在外層,則需要進行 20 萬次表連接,從而浪費資源,增加消耗 ;

綜上:
小表驅動大表的主要目的是通過減少表連接創建的次數,加快查詢速度 。

  1. 怎么區分那個是驅動表與被驅動表 ?
    通過 EXPLAIN 查看 SQL 語句的執行計划可以判斷在誰是驅動表,EXPLAIN 語句分析出來的第一行的表即是驅動表 ;

  2. 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM