mysql如何關聯 MySQL 如何執行關聯查詢

2021-10-18 01:54:06 字數 4868 閱讀 9840

當前mysql執行的策略很簡單:mysql對任何關聯都執行巢狀迴圈操作,即mysql先在乙個表中迴圈取出單條資料,然後再巢狀迴圈到下乙個表中尋打匹配的行,依次下去,直到描述到所表表中匹配的行為止。然後根據各個表匹配的行,返回查詢中需要的各個列。mysql會嘗試在最後乙個關聯表中打到所有匹配的行,如果最後乙個關聯表無法找到更多的行以後,mysql返回到上一層次關聯表,看是否能夠找到更多的匹配記錄,依此類推迭代執行。

select tbl1.col1,tbl2.col2

from tbl1 inner join tbl2 using(col3)

where tbl1.col1 in(5,6);

假設mysql按照查詢中的表順序進行關聯操作,我們則可以用下面的偽**表示mysql將如何完成這個查詢:

outer_iter = iterator_over tbl1 where col1 in(3,4)

outer_row = outer_iter.next

while outer_row

inner_iter = iterator over tbl2 where col3=outer_row.col3

inner_row = inner_iter.next

while inner_row

output[outer_row.col1,inner_row.col2]

inner_row = inner_iter.next

endout_row = outer_iter.next

end上面的執行計畫對於單錶查詢和多表關聯查詢都適用,如果是乙個單錶查詢,那麼只需要完成上面的外層的基本操作。對於外連線和上面的執行過程任然適用。例如我們將上面的查詢修改如下:

select tbl1.col1 ,tbl2.col2 from tbl1 left outer join tbl2 using (col3) where tbl1.col1 in (3,4)

對應的偽**:

outer_iter = iterator over tbl1 where col1 in(3,4)

outer row = outer_iter.next

while outer_row

inner_iter = iterator over tbl2 where col3 = outer_row.col3

inner_row = inner_iter.next

if inner row -> 手動加粗

while inner_row

out_put [outer_row.col1,inner_row.col2]

inner_row = inner_iter.next

endelse -> 手動加粗

out_put[outer_row.col1,null] -> 手動加粗

endouter_row = outer_iter.next

end從上面兩個例子也可以看出,對於主表來說,是先進行主表的where條件篩選,再進行表聯接,而不是先進行整表聯接再進行where條件的篩選。

舉個例子:

資料表結構:

mysql> create table a(

-> id int unsigned not null primary key

mysql> create table b like a;

表中資料:

mysql> select * from a;

| id |

| 1 |

| 2 |

| 3 |

| 4 |

| 5 |

5 rows in set (0.00 sec)

mysql> select * from b;

| id |

| 4 |

| 5 |

| 6 |

| 7 |

4 rows in set (0.00 sec)

explain查詢:

mysql> explain select a.id as aid,b.id as bid from a left join b using(id) where a.id>3;

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | extra |

| 1 | ****** | a | range | primary | primary | 4 | null | 3 | using where; using index |

| 1 | ****** | b | eq_ref | primary | primary | 4 | com.a.id | 1 | using index |

2 rows in set (0.00 sec)

可以看出,首先在a表上進行範圍查詢,篩選出a.id>3的資料,然後在進行"巢狀查詢"。

注意,on後面的篩選條件主要是針對的是關聯表,而對於主表篩選並不適用,比如:

mysql> select a.id as aid,b.id as bid from a left join b on a.id=b.id and a.id>3;

| aid | bid |

| 1 | null |

| 2 | null |

| 3 | null |

| 4 | 4 |

| 5 | 5 |

5 rows in set (0.00 sec)

mysql> explain select a.id as aid,b.id as bid from a left join b on a.id=b.id and a.id>3;

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | extra |

| 1 | ****** | a | index | null | primary | 4 | null | 5 | using index |

| 1 | ****** | b | eq_ref | primary | primary | 4 | com.a.id | 1 | using index |

2 rows in set (0.00 sec)

我們發現a表的id<=3的資料並未被篩選走,explain的結果是a表進行了index型別的查詢,即主鍵索引的全部掃瞄。

如果在on的篩選條件是針對b表的呢,情況會怎麼樣?

下面的例子資料表結構和資料變了,我們只關注查詢的結果區別:

mysql> select * from a left join b on a.data=b.data and b.id<=20;

| id | data | id | data |

| 1 | 1 | null | null |

| 2 | 2 | null | null |

| 3 | 3 | null | null |

| 4 | 4 | 1 | 4 |

| 4 | 4 | 6 | 4 |

| 4 | 4 | 11 | 4 |

| 4 | 4 | 16 | 4 |

| 5 | 5 | 2 | 5 |

| 5 | 5 | 7 | 5 |

| 5 | 5 | 12 | 5 |

| 5 | 5 | 17 | 5 |

11 rows in set (0.00 sec)

mysql> select * from a left join b on a.data=b.data where b.id<=20;

| id | data | id | data |

| 4 | 4 | 1 | 4 |

| 5 | 5 | 2 | 5 |

| 4 | 4 | 6 | 4 |

| 5 | 5 | 7 | 5 |

| 4 | 4 | 11 | 4 |

| 5 | 5 | 12 | 5 |

| 4 | 4 | 16 | 4 |

| 5 | 5 | 17 | 5 |

8 rows in set (0.00 sec)

由此,我們可以根據偽碼來分析兩者的區別:

outer_iter = iterator over a

outer row = outer_iter.next

while outer_row

inner_iter = iterator over b where data = outer_row.date where id<=20

inner_row = inner_iter.next

if inner row

while inner_row

out_put [outer_row,inner_row]

inner_row = inner_iter.next

endelse

out_put[outer_row,null]

endouter_row = outer_iter.next

endouter_iter = iterator over a

outer row = outer_iter.next

while outer_row

inner_iter = iterator over b where data = outer_row.date ->手動加粗

inner_row = inner_iter.next

if inner row

while inner_row

out_put [outer_row,inner_row]

inner_row = inner_iter.next

endelse

out_put[outer_row,null]

endouter_row = outer_iter.next

endleft join的結果集中 where b.id<=20 ->手動加粗

mysql如何關聯 MySQL如何執行關聯查詢

mysql中 關聯 join 一詞包含的意義比一般意義上理解的要更廣泛。總的來說,mysql認為任何乙個查詢都是一次 關聯 並不僅僅是乙個查詢需要到兩個表的匹配才叫關聯,索引在mysql中,每乙個查詢,每乙個片段 包括子查詢,設定基於表單的select 都可能是關聯。所以,理解mysql如何執行關聯...

mysql 關聯刪除 mysql如何刪除關聯表

mysql資料庫中,表與表之間進行關聯之後,就不可隨意的進行刪除操作,否則會影響所有關聯表之間的結構,那麼如何安全的刪除關聯表呢,讓我們來了解一下。mysql使用drop命令刪除關聯表,方法為 1.刪除表的外來鍵約束 外來鍵是乙個特殊字段,其將某乙個表與其父表建立關聯關係。在建立表的時候,外來鍵約束...

mysql關聯子查詢 MySQL 關聯子查詢

mysql 關聯子查詢 關聯子查詢是指乙個包含對錶的引用的子查詢,該錶也顯示在外部查詢中。通俗一點來講,就是子查詢引用到了主查詢的資料資料。以乙個實際的例子來理解關聯子查詢 article 文章表 aidtitlecontentuid 文章1文章1正文內容.文章2文章2正文內容.文章3文章3正文內容...