mysql默认join是什么类型_mysql 关于join的总结

本文地址:http://www.cnblogs.com/qiaoyihang/p/6401280.html

mysql不支持Full join,不过可以通过UNION 关键字来合并 LEFT JOIN 与 RIGHT JOIN来模拟FULL join.

Cross join

cross join:交叉连接,得到的结果是两个表的乘积,即笛卡尔积

笛卡尔(Descartes)乘积又叫直积。假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)}。可以扩展到多个集合的情况。类似的例子有,如果A表示某学校学生的集合,B表示该学校所有课程的集合,则A与B的笛卡尔积表示所有可能的选课情况。

实际上,在 MySQL 中(仅限于 MySQL) CROSS JOIN 与 INNER JOIN 的表现是一样的,在不指定 ON 条件得到的结果都是笛卡尔积,反之取得两个表完全匹配的结果。

INNER JOIN 与 CROSS JOIN 可以省略 INNER 或 CROSS 关键字,因此下面的 SQL 效果是一样的:

... FROM table1 INNER JOINtable2

...FROM table1 CROSS JOINtable2

...FROM table1 JOIN table2

性能优化

1.显示(explicit) inner join VS 隐式(implicit) inner join

select * from

table a inner join tablebon a.id = b.id;

VS

select a.*, b.*

from table a, tablebwhere a.id = b.id;

我在数据库中比较(10w数据)得之,它们用时几乎相同,第一个是显示的inner join,后一个是隐式的inner join。

2.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 子句条件才会被使用。它将从匹配阶段产生的数据中检索过滤。

PASS

select * fromAinner join B on B.name =A.nameleft join C on C.name =B.nameleft join D on D.id =C.idwhere C.status>1 and D.status=1;

Great

select * fromAinner join B on B.name =A.nameleft join C on C.name = B.name and C.status>1

left join D on D.id = C.id and D.status=1

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

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

mysql> SELECT * FROM product LEFT JOINproduct_detailsON (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.00sec)

mysql> SELECT * FROM product LEFT JOINproduct_detailsON (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);

Great

insert intot1(a1)select b1 fromt2left join (select distinct t1.id from t1 ) t1 on t1.id =t2.r_idwhere t1.id is null;

关于join on where

数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。

在使用left jion时,on和where条件的区别如下:1、on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。

假设有两张表:

表1:tab1

id size1 10

2 20

3 30表2:tab2

size name10AAA20BBB20CCC

两条SQL:1、select * from tab1 left join tab2 on tab1.size = tab2.size where tab2.name='AAA'

2、select * from tab1 left join tab2 on tab1.size = tab2.size and tab2.name='AAA'第一条SQL的过程:1、中间表

on条件:

tab1.size=tab2.size

tab1.id tab1.size tab2.size tab2.name1 10 10AAA2 20 20BBB2 20 20CCC3 30 (null) (null)2、再对中间表过滤where条件:

tab2.name='AAA'tab1.id tab1.size tab2.size tab2.name1 10 10AAA

第二条SQL的过程:1、中间表

on条件:

tab1.size= tab2.size and tab2.name='AAA'(条件不为真也会返回左表中的记录) tab1.id tab1.size tab2.size tab2.name1 10 10AAA2 20 (null) (null)3 30 (null) (null)

其实以上结果的关键原因就是leftjoin,right join,fulljoin的特殊性,

不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。

而inner jion没这个特殊性,则条件放在on中和where中,返回的结果集是相同的。

MySQL STRAIGHT_JOIN 与 NATURAL JOIN

STRAIGHT_JOIN 实际上与内连接 INNER JOIN 表现完全一致,不同的是使用了 STRAIGHT_JOIN 后,table1 会先于 table2 载入。

提示

MySQL 在执行 INNER JOIN 的时候,会根据自己内部的优化规则来决定先载入 table1 还是 table2,如果您确认 MySQL 载入表的顺序并不是最优化的时候,就可以使用 STRAIGHT_JOIN 以替代 INNER JOIN。

NATURAL JOIN 也叫自然连接,实际是属于 JOIN 的一种

使用 NATURAL JOIN 时,MySQL 将表中具有相同名称的字段自动进行记录匹配,而这些同名字段类型可以不同。因此,NATURAL JOIN 不用指定匹配条件。

NATURAL JOIN 默认是同名字段完全匹配的 INNER JOIN,也可以使用 LEFT JOIN 或 RIGHT JOIN

文章借鉴:http://www.cnblogs.com/BeginMan/p/3754322.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值