欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL中的表連接原理分析

 更新時(shí)間:2025年06月26日 14:20:39   作者:在成都搬磚的鴨鴨  
這篇文章主要介紹了MySQL中的表連接原理分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

1、背景

在進(jìn)行sql查詢時(shí)有時(shí)需要多張表的查詢結(jié)果組成一個(gè)共同的結(jié)果返回,這時(shí)就用到了mysql中連接的用法,接下來(lái)就以兩張表來(lái)講解表連接的原理。

2、環(huán)境

創(chuàng)建兩張表并插入數(shù)據(jù)如下:

mysql> select * from testjoin1;
+----+------+------+
| id | str1 | num1 |
+----+------+------+
|  1 | aaa  |  111 |
|  2 | bbb  |  222 |
|  3 | ccc  |  333 |
+----+------+------+
3 rows in set (0.00 sec)

mysql> select * from testjoin2;
+----+------+------+
| id | str2 | num2 |
+----+------+------+
|  1 | bbb  |  333 |
|  2 | ccc  |  444 |
|  3 | ddd  |  555 |
+----+------+------+
3 rows in set (0.00 sec)

3、表連接原理

【1】驅(qū)動(dòng)表和被驅(qū)動(dòng)表

兩張表連接查詢過(guò)程為:

  • 1、先確定第一張要查詢的表得到第一張表的查詢結(jié)果,
  • 2、第一張表的查詢結(jié)果作為第二張表的查詢條件進(jìn)行查詢得到最終查詢結(jié)果。

其中第一張表叫驅(qū)動(dòng)表,第二張表叫被驅(qū)動(dòng)表,先看一下最基本連接查詢的例子:

mysql> select * from testjoin1, testjoin2;
+----+------+------+----+------+------+
| id | str1 | num1 | id | str2 | num2 |
+----+------+------+----+------+------+
|  3 | ccc  |  333 |  1 | bbb  |  333 |
|  2 | bbb  |  222 |  1 | bbb  |  333 |
|  1 | aaa  |  111 |  1 | bbb  |  333 |
|  3 | ccc  |  333 |  2 | ccc  |  444 |
|  2 | bbb  |  222 |  2 | ccc  |  444 |
|  1 | aaa  |  111 |  2 | ccc  |  444 |
|  3 | ccc  |  333 |  3 | ddd  |  555 |
|  2 | bbb  |  222 |  3 | ddd  |  555 |
|  1 | aaa  |  111 |  3 | ddd  |  555 |
+----+------+------+----+------+------+
9 rows in set (0.00 sec)

再看一下執(zhí)行計(jì)劃:

mysql> explain select * from testjoin1, testjoin2;
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+----------------
---------------+
| id | select_type | table     | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra
               |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+----------------
---------------+
|  1 | SIMPLE      | testjoin1 | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |   100.00 | NULL
               |
|  1 | SIMPLE      | testjoin2 | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |   100.00 | Using join buff
er (hash join) |
+----+-------------+-----------+------------+------+---------------+------+---------+------+------+----------+----------------
---------------+
2 rows in set, 1 warning (0.00 sec)

可以看到執(zhí)行計(jì)劃輸出了兩條,第一條代表testjoin1表是驅(qū)動(dòng)表, testjoin2表是被驅(qū)動(dòng)表。

【2】?jī)?nèi)連接

驅(qū)動(dòng)表的查詢結(jié)果作為查詢條件但沒(méi)有在被驅(qū)動(dòng)表中匹配到結(jié)果時(shí),這條記錄就不會(huì)加入到最終結(jié)果集中,這種連接方式就叫內(nèi)連接,例如:

mysql> select * from testjoin1 inner join testjoin2 on str1=str2;
+----+------+------+----+------+------+
| id | str1 | num1 | id | str2 | num2 |
+----+------+------+----+------+------+
|  2 | bbb  |  222 |  1 | bbb  |  333 |
|  3 | ccc  |  333 |  2 | ccc  |  444 |
+----+------+------+----+------+------+
2 rows in set (0.00 sec)

可以看到testjoin1表中str1為aaa的記錄就不在查詢結(jié)果中,用圖紅色部分表示:

在這里插入圖片描述

【3】外連接

與內(nèi)連接相對(duì)應(yīng)的就是外連接,外連接中驅(qū)動(dòng)表的查詢結(jié)果作為查詢條件即使沒(méi)有在被驅(qū)動(dòng)表中查到,也會(huì)展示在最終結(jié)果集中,外連接分為左外連接和右外連接,左外連接就是將左邊的表作為驅(qū)動(dòng)表,左外連接查詢?nèi)缦拢?/p>

mysql> select * from testjoin1 left join testjoin2 on str1=str2;
+----+------+------+------+------+------+
| id | str1 | num1 | id   | str2 | num2 |
+----+------+------+------+------+------+
|  1 | aaa  |  111 | NULL | NULL | NULL |
|  2 | bbb  |  222 |    1 | bbb  |  333 |
|  3 | ccc  |  333 |    2 | ccc  |  444 |
+----+------+------+------+------+------+
3 rows in set (0.00 sec)

用圖紫色部分表示:

在這里插入圖片描述

右外連接就是將右邊的表作為驅(qū)動(dòng)表,右外連接查詢?nèi)缦拢?/p>

mysql> select * from testjoin1 right join testjoin2 on str1=str2;
+------+------+------+----+------+------+
| id   | str1 | num1 | id | str2 | num2 |
+------+------+------+----+------+------+
|    2 | bbb  |  222 |  1 | bbb  |  333 |
|    3 | ccc  |  333 |  2 | ccc  |  444 |
| NULL | NULL | NULL |  3 | ddd  |  555 |
+------+------+------+----+------+------+
3 rows in set (0.00 sec)

用圖綠色部分表示:

在這里插入圖片描述

【4】嵌套循環(huán)連接

驅(qū)動(dòng)表只會(huì)被訪問(wèn)一次,被驅(qū)動(dòng)表可能被訪問(wèn)多次,取決于從驅(qū)動(dòng)表中得到的結(jié)果,這種連接執(zhí)行方式就叫嵌套循環(huán)連接。

【5】join buffer

mysql中的查表過(guò)程就是把數(shù)據(jù)從磁盤中加載到內(nèi)存進(jìn)行比較查詢,加載后面的記錄時(shí)會(huì)釋放內(nèi)存中前面已經(jīng)使用過(guò)的記錄,我們上面說(shuō)過(guò)被驅(qū)動(dòng)表可能會(huì)被訪問(wèn)很多次,每次都從磁盤重新加載數(shù)據(jù)到內(nèi)存無(wú)疑會(huì)增加開(kāi)銷,所以提出了join buffer,也就是存儲(chǔ)驅(qū)動(dòng)表的所有查詢結(jié)過(guò),然后只執(zhí)行一次將被驅(qū)動(dòng)表從磁盤加載到內(nèi)存中,在內(nèi)存中計(jì)算得到最終查詢結(jié)果,前面測(cè)試連接的explain語(yǔ)句中就可以看到被驅(qū)動(dòng)表的Extra字段中有Using join buffer。

4、總結(jié)

對(duì)驅(qū)動(dòng)表進(jìn)行查詢時(shí)就相當(dāng)于單表查詢,也可以通過(guò)索引去優(yōu)化查詢速度,當(dāng)確定了驅(qū)動(dòng)表的查詢結(jié)果時(shí),其實(shí)被驅(qū)動(dòng)的查詢條件也就確定了,也可以通過(guò)加索引去優(yōu)化查詢速度,當(dāng)然索引是否生效還要看和全表掃描的執(zhí)行效率進(jìn)行對(duì)比。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論