join用法和性能浅析

一、JOIN用法

JOIN 分为:内连接(INNER JOIN)、外连接(OUTER JOIN)。其中,外连接分为:左外连接(LEFT OUTER JOIN)、右外连接(RIGHT OUTER JOIN)、全外连接(FULL OUTER JOIN),其中外连接的“OUTER”关键字可以省略不写。

例:
表A有列ID,值为:
1
2
3
4

表B有列ID,值为:
3
4
5
6

1.内连接(显示左右两表能完全匹配的数据):

select A.ID, B.ID from A INNER JOIN B ON A.ID = B.ID

结果为:
3 3
4 4

这里写图片描述

2.左外连接(显示左表所有数据,右表匹配不上的显示为NULL):

select A.ID, B.ID from A LEFT JOIN B ON A.ID = B.ID

结果为:
1 NULL
2 NULL
3 3
4 4

这里写图片描述

如果想只从左表(A)中产生一套记录,但不包含右表(B)的记录,可以通过设置where语句来执行,如下:

select A.ID, B.ID from A LEFT JOIN B ON A.ID = B.ID WHERE A.ID is NULL or B.ID is NULL

结果为:
1 NULL
2 NULL

这里写图片描述

3.右外连接(显示右表所有数据,左表匹配不上的显示为NULL):

select A.ID, B.ID from A RIGHT JOIN B ON A.ID = B.ID

结果为:
3 3
4 4
NULL 5
NULL 6

同LEFT JOIN。

4.全外连接(显示左右两量表所有数据,两表匹配不上的显示为NULL):

select A.ID, B.ID from A FULL OUTER JOIN B ON A.ID = B.ID

结果为:
1 NULL
2 NULL
3 3
4 4
NULL 5
NULL 6

这里写图片描述

二、性能优化

left join/right join VS inner join

尽量用inner join.避免 LEFT JOIN 和 NULL.
在使用left join(或right join)时,应该清楚的知道以下几点:

1. on与 where的执行顺序
ON 条件(“A LEFT JOIN B ON 条件表达式”中的ON)用来决定如何从 B 表中检索数据行。如果 B 表中没有任何一行数据匹配 ON 的条件,将会额外生成一行所有列为 NULL 的数据,在匹配阶段 WHERE 子句的条件都不会被使用。仅在匹配阶段完成以后,WHERE 子句条件才会被使用。它将从匹配阶段产生的数据中检索过滤。
所以我们要注意:在使用Left (right) join的时候,一定要在先给出尽可能多的匹配满足条件,减少Where的执行。如:

使用where:

select * from A
inner join B on B.id = A.id
left join C on C.id = B.id
left join D on D.id = C.id
where C.id>1 and D.id=1;

不使用where:

select * from A
inner join B on B.id = A.id
left join C on C.id = B.id and C.id>1
left join D on D.id = C.id and D.id=1

从上面例子可以看出,尽可能满足ON的条件,而少用Where的条件。从执行性能来看第二个显然更加省时。

2.注意ON 子句和 WHERE 子句的不同


mysql> SELECT * FROM product LEFT JOIN product_details
       ON (product.id = product_details.id)
       AND product_details.id=2;
+----+--------+------+--------+-------+
| id | amount | id   | weight | exist |
+----+--------+------+--------+-------+
|  1 |    100 | NULL |   NULL |  NULL |
|  2 |    200 |    2 |     22 |     0 |
|  3 |    300 | NULL |   NULL |  NULL |
|  4 |    400 | NULL |   NULL |  NULL |
+----+--------+------+--------+-------+
4 rows in set (0.00 sec)
mysql> SELECT * FROM product LEFT JOIN product_details
       ON (product.id = product_details.id)
       WHERE product_details.id=2;
+----+--------+----+--------+-------+
| id | amount | id | weight | exist |
+----+--------+----+--------+-------+
|  2 |    200 |  2 |     22 |     0 |
+----+--------+----+--------+-------+
1 row in set (0.01 sec)

从上可知,第一条查询使用 ON 条件决定了从 LEFT JOIN的 product_details表中检索符合的所有数据行。第二条查询做了简单的LEFT JOIN,然后使用 WHERE 子句从 LEFT JOIN的数据中过滤掉不符合条件的数据行。

3.尽量避免子查询,而用join

往往性能这玩意儿,更多时候体现在数据量比较大的时候,此时,我们应该避免复杂的子查询。如下:
Pass

insert into t1(a1) select b1 from t2 where not exists(select 1 from t1 where t1.id = t2.r_id); 

Creat

insert into t1(a1)  
select b1 from t2  
left join (select distinct t1.id from t1 ) t1 on t1.id = t2.r_id   
where t1.id is null;  
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
根据引用\[1\],MySQL在优化过程中引入了Index Nested-Loop Join和Block Nested-Loop Join两种算法来执行join查询。其中,Index Nested-Loop Join可以减少内层表数据的匹配次数。而根据引用\[2\],left join和inner join是两种不同的连接方式。left join会保留左表的所有数据,如果右表没有相关数据,则会显示null。而inner join只会返回两个表在on条件相匹配的结果集。根据引用\[3\],left join和inner join的使用原则是根据需求来选择,如果需要保留左表的所有数据,可以使用left join,如果只需要匹配的结果集,可以使用inner join。至于性能方面,具体的性能取决于具体的查询和数据情况,无法一概而论。 #### 引用[.reference_title] - *1* *3* [详解 Mysql LEFT JOINJOIN查询区别及原理](https://blog.csdn.net/agonie201218/article/details/106993948)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [MySQL中inner join/left join连表查询的查询速度](https://blog.csdn.net/GCRXJQ/article/details/126298550)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值