新聞中心
連接(Join)是將兩個或多個表、視圖或物化視圖的結合在一起的查詢。當查詢的 ?FROM? 子句中出現多個表時 OceanBase 數據庫會進行連接查詢,查詢輸出列可以從 ?FROM? 子句任何表中選取。 如果多個表都有一個列名,那么您必須用表名限定查詢過程中對這些列的所有引用。數據庫中的連接類型一般包括 ?inner join?、?outer join?、?semi-join? 和 ?anti-join?。其中 ?Semi-join? 和 ?Anti-join? 都是通過子查詢改寫得到,OceanBase 本身并沒有表述 ?Anti-join? 和 ?Semi-join? 的語法。

創(chuàng)新互聯公司2013年開創(chuàng)至今,是專業(yè)互聯網技術服務公司,擁有項目成都網站建設、網站制作網站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元綦江做網站,已為上家服務,為綦江各地企業(yè)和個人服務,聯系電話:18980820575
連接條件
連接條件是將多表結合在一起的規(guī)則,存在于從句或 ?WHERE? 子句中,用于比較來自不同的表兩列,多數連接至少包含一個連接條件。連接條件可以分為等值連接(比如 t1.a = t2.b)和非等值連接(t1.a < t2.b),相比于非等值連接條件, 等值連接條件允許數據庫使用高效的連接算法,比如 ?Hash Join? 和 ?Merge-Sort join?。
為了執(zhí)行連接,OceanBase 從不同表取行組合成對,使用連接條件進行匹配。 要執(zhí)行兩表以上的多表連接,OceanBase 首先根據比較它們的列的連接條件連接其中的兩個表,然后根據包含連接表和新表列的連接條件將結果連接到另一個表。優(yōu)化器根據連接條件、基表索引以及可用統(tǒng)計信息確定 OceanBase 連接順序。
?WHERE? 子句除了連接條件還可能含有其他條件,這些僅引用一個表的條件可以進一步限制連接查詢返回的行數。
等值連接(EQUI-JOINS)
等值連接(Equijoins)是連接條件包含等式運算符的連接。進行等值連接時將特定列滿足等值條件的行進行組合輸出。
自連接(SELF-JOIN)
自連接是表與其自身的連接。該表在 ?FROM? 子句中出現兩次,后跟表別名,這些別名限定聯接條件中的列名。執(zhí)行自連接時OceanBase數據庫將組合并返回滿足連接條件的行。
笛卡兒積(Cartesian Products)
如果連接查詢中的兩個表沒有連接條件,OceanBase 數據庫返回其笛卡爾乘積,使用第一個表的每一行與另一表每一個行進行組合輸出。笛卡爾乘積總是生成許多行,很少有用。 例如,兩個都有 100 行的表的笛卡爾積有 10,000 行。除非您特別需要笛卡爾乘積,否則始終包括一個連接條件。 如果查詢連接了三個或多個表,并且沒有為特定對指定連接條件,則優(yōu)化器可以選擇避免生成中間笛卡爾乘積的連接順序。
內連接(INNER JOIN)
內連接(INNER JOIN)是數據庫中最基本的連接操作。內連接基于連接條件將兩張表(如 A 和 B)的列組合在一起,產生新的結果表。查詢會將 A 表的每一行和 B 表的每一行進行比較,并找出滿足連接條件的組合。當連接條件被滿足,A 和 B 中匹配的行會按列組合(并排組合)成結果集中的一行。連接產生的結果集等于首先對兩張表做笛卡爾積,將 A 中的每一行和 B 中的每一行組合,然后返回滿足連接條件的記錄。
外連接(OUTER JOIN)
外連接(OUTER JOIN) 返回滿足連接條件的所有行,同時從一個表返回沒有使用的行,在另一個表相應位置填充 ?NULL?。外連接可依據連接表保留左表、右表或全部表的行而進一步分為左連接、右連接和全連接。其中左連接(LEFT [OUTER] JOIN)中左表行未在右表匹配到行時,在右表自動填充 ?NULL?。右連接(RIGHT [OUTER] JOIN)中右表行未在左表匹配到行時,在左表自動填充 ?NULL?。全連接(FULL [OUTER] JOIN)左表或者右表未在其它表匹配到行時均會填充 ?NULL?。
SEMI 連接(SEMI-JOIN)
當 A 表和 B 表進行 ?LEFT? 或 ?RIGHT ANTI-JOIN? 的時候,它只返回 A 或 B 中所有能夠在 B 或 A 中找到匹配的行。?SEMI-JOIN? 只能通過子查詢展開得到。
ANTI 連接(ANTI-JOIN)
當 A 表和 B 表進行 ?LEFT? 或 ?RIGHT ANTI-JOIN? 的時候,它只返回 A 或 B 中所有不能在 B 或 A 中找到匹配的行。類似于 ?SEMI-JOIN?,?ANTI-JOIN? 也只能通過子查詢展開得到。
示例
建立表 table_a 和表 table_b,并插入數據。執(zhí)行以下語句:
CREATE TABLE table_a(PK INT, name VARCHAR(25));
INSERT INTO table_a VALUES(1,'??怂?);
INSERT INTO table_a VALUES(2,'警察');
INSERT INTO table_a VALUES(3,'的士');
INSERT INTO table_a VALUES(4,'林肯');
INSERT INTO table_a VALUES(5,'亞利桑那州');
INSERT INTO table_a VALUES(6,'華盛頓');
INSERT INTO table_a VALUES(7,'戴爾');
INSERT INTO table_a VALUES(10,'朗訊');
CREATE TABLE table_b(PK INT, name VARCHAR(25));
INSERT INTO table_b VALUES(1,'??怂?);
INSERT INTO table_b VALUES(2,'警察');
INSERT INTO table_b VALUES(3,'的士');
INSERT INTO table_b VALUES(6,'華盛頓');
INSERT INTO table_b VALUES(7,'戴爾');
INSERT INTO table_b VALUES(8,'微軟');
INSERT INTO table_b VALUES(9,'蘋果');
INSERT INTO table_b VALUES(11,'蘇格蘭威士忌');自連接查詢(SELF-JOIN):
SELECT * FROM table_a ta, table_a tb WHERE ta.NAME = tb.NAME;查詢結果如下:
+------+-----------------+------+-----------------+
| PK | NAME | PK | NAME |
+------+-----------------+------+-----------------+
| 1 | ??怂? | 1 | ??怂? |
| 2 | 警察 | 2 | 警察 |
| 3 | 的士 | 3 | 的士 |
| 4 | 林肯 | 4 | 林肯 |
| 5 | 亞利桑那州 | 5 | 亞利桑那州 |
| 6 | 華盛頓 | 6 | 華盛頓 |
| 7 | 戴爾 | 7 | 戴爾 |
| 10 | 朗訊 | 10 | 朗訊 |
+------+-----------------+------+-----------------+內連接(INNER JOIN)查詢:
SELECT A.PK AS A_PK, A.name AS A_Value, B.PK AS B_PK, B.name AS B_Value
FROM table_a A INNER JOIN table_b B ON A.PK = B.PK;查詢結果如下:
+------+-----------+------+-----------+
| A_PK | A_VALUE | B_PK | B_VALUE |
+------+-----------+------+-----------+
| 1 | ??怂? | 1 | ??怂? |
| 2 | 警察 | 2 | 警察 |
| 3 | 的士 | 3 | 的士 |
| 6 | 華盛頓 | 6 | 華盛頓 |
| 7 | 戴爾 | 7 | 戴爾 |
+------+-----------+------+-----------+左連接查詢:
SELECT A.PK AS A_PK, A.name AS A_Value, B.PK AS B_PK, B.name AS B_Value
FROM table_a A LEFT JOIN table_b B ON A.PK = B.PK;查詢結果如下:
+------+-----------------+------+-----------+
| A_PK | A_VALUE | B_PK | B_VALUE |
+------+-----------------+------+-----------+
| 1 | ??怂? | 1 | ??怂? |
| 2 | 警察 | 2 | 警察 |
| 3 | 的士 | 3 | 的士 |
| 6 | 華盛頓 | 6 | 華盛頓 |
| 7 | 戴爾 | 7 | 戴爾 |
| 4 | 林肯 | NULL | NULL |
| 5 | 亞利桑那州 | NULL | NULL |
| 10 | 朗訊 | NULL | NULL |
+------+-----------------+------+-----------+右連接查詢:
obclient> SELECT A.PK AS A_PK, A.name AS A_Value, B.PK AS B_PK, B.name AS B_Value FROM table_a A RIGHT JOIN table_b B ON A.PK = B.PK;查詢結果如下:
+------+-----------+------+--------------------+
| A_PK | A_VALUE | B_PK | B_VALUE |
+------+-----------+------+--------------------+
| 1 | ??怂? | 1 | ??怂? |
| 2 | 警察 | 2 | 警察 |
| 3 | 的士 | 3 | 的士 |
| 6 | 華盛頓 | 6 | 華盛頓 |
| 7 | 戴爾 | 7 | 戴爾 |
| NULL | NULL | 8 | 微軟 |
| NULL | NULL | 9 | 蘋果 |
| NULL | NULL | 11 | 蘇格蘭威士忌 |
+------+-----------+------+--------------------+全連接查詢:
obclient> SELECT A.PK AS A_PK,A.name AS A_Value,B.PK AS B_PK,B.name AS B_Value FROM table_a A FULL JOIN table_b B ON A.PK = B.PK;查詢結果如下:
+------+-----------------+------+--------------------+
| A_PK | A_VALUE | B_PK | B_VALUE |
+------+-----------------+------+--------------------+
| 1 | 福克斯 | 1 | ??怂? |
| 2 | 警察 | 2 | 警察 |
| 3 | 的士 | 3 | 的士 |
| 6 | 華盛頓 | 6 | 華盛頓 |
| 7 | 戴爾 | 7 | 戴爾 |
| NULL | NULL | 8 | 微軟 |
| NULL | NULL | 9 | 蘋果 |
| NULL | NULL | 11 | 蘇格蘭威士忌 |
| 4 | 林肯 | NULL | NULL |
| 5 | 亞利桑那州 | NULL | NULL |
| 10 | 朗訊 | NULL | NULL |
+------+-----------------+------+--------------------+Semi 連接(semi-join):有依賴關系的子查詢被展開改寫成 SEMI-JOIN。
explain SELECT * FROM table_a t1 WHERE t1.PK IN (SELECT t2.PK FROM table_b t2 WHERE t2.NAME = t1.NAME);查詢結果如下:
+------------------------------------------------+
| Query Plan |
+------------------------------------------------+
=======================================
|ID|OPERATOR |NAME|EST. ROWS|COST|
---------------------------------------
|0 |HASH SEMI JOIN| |8 |114 |
|1 | TABLE SCAN |T1 |8 |38 |
|2 | TABLE SCAN |T2 |8 |38 |
=======================================
Outputs & filters:
-------------------------------------
0 - output([T1.PK], [T1.NAME]), filter(nil),
equal_conds([T1.PK = T2.PK], [T2.NAME = T1.NAME]), other_conds(nil)
1 - output([T1.NAME], [T1.PK]), filter(nil),
access([T1.NAME], [T1.PK]), partitions(p0)
2 - output([T2.NAME], [T2.PK]), filter(nil),
access([T2.NAME], [T2.PK]), partitions(p0)
+------------------------------------------------+Anti 連接(anti-join):有依賴關系的子查詢被改寫成 ?Anti-join?。
EXPLAIN SELECT * FROM table_a t1 WHERE t1.PK NOT IN (SELECT t2.PK
FROM table_b t2 WHERE t2.name = t1.name);查詢結果如下:
+------------------------------------------------+
| Query Plan |
+------------------------------------------------+
=======================================
|ID|OPERATOR |NAME|EST. ROWS|COST|
---------------------------------------
|0 |HASH ANTI JOIN| |0 |112 |
|1 | TABLE SCAN |T1 |8 |38 |
|2 | TABLE SCAN |T2 |8 |38 |
=======================================
Outputs & filters:
-------------------------------------
0 - output([T1.PK], [T1.NAME]), filter(nil),
equal_conds([T2.NAME = T1.NAME]), other_conds([(T_OP_OR, T1.PK = T2.PK,
(T_OP_IS, T1.PK, NULL, 0), (T_OP_IS, T2.PK, NULL, 0))])
1 - output([T1.NAME], [T1.PK]), filter(nil),
access([T1.NAME], [T1.PK]), partitions(p0)
2 - output([T2.NAME], [T2.PK]), filter(nil),
access([T2.NAME], [T2.PK]), partitions(p0)
+---------------------------------------------------------+ 當前文章:創(chuàng)新互聯OceanBase教程:OceanBase連接
當前網址:http://www.dlmjj.cn/article/dpcehph.html


咨詢
建站咨詢
