mysql JOIN要点

基础概念:

内外联结的区别是内联结将去除所有不符合条件的记录,而外联结则保留其中部分。外左联结与外右联结的区别在于如果用A左联结B则A中所有记录都会保留在结果中,此时B中只有符合联结条件的记录,而右联结相反,这样也就不会混淆了。

差集:

select table1.* from table1 left join table2 using(id) where table2.id is null

交集:

select table1.* from table1 left join table2 using(id)

性能:

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

select * from table a inner join table b on a.id = b.id;

VS

select a.*, b.* from table a, table b where a.id = b.id;

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

2:left join/right join VS inner join 尽量用inner join.避免 LEFT JOIN 和 NULL.

3:on与 where的执行顺序:

ON 条件(“A LEFT JOIN B ON 条件表达式”中的ON)用来决定如何从 B 表中检索数据行。如果 B 表中没有任何一行数据匹配 ON 的条件,将会额外生成一行所有列为 NULL 的数据,在匹配阶段 WHERE 子句的条件都不会被使用。仅在匹配阶段完成以后,WHERE 子句条件才会被使用。ON将从匹配阶段产生的数据中检索过滤。

所以我们要注意:在使用Left (right) join的时候,一定要在先给出尽可能多的匹配满足条件,减少Where的执行。如:

PASS

代码如下:

select * from A

inner join B on B.name = A.name

left join C on C.name = B.name

left join D on D.id = C.id

where C.status>1 and D.status=1;

Great

代码如下:

select * from A

inner join B on B.name = A.name

left 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的条件。从执行性能来看第二个显然更加省时。

4:注意ON 子句和 WHERE 子句的不同

代码如下:

SELECT * FROM product LEFT JOIN product_details

ON (product.id = product_details.id)

AND product_details.id=2;

SELECT * FROM product LEFT JOIN product_details

ON (product.id = product_details.id)

WHERE product_details.id=2;

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

5: 尽量避免子查询,而用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 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;  

你可能感兴趣的:(mysql JOIN要点)