MYSQl left join联合查询效率分析

user表:

id | name
———
1 | libk
2 | zyfon
3 | daodao

user_action表:

user_id | action
—————
1 | jump
1 | kick
1 | jump
2 | run
4
| swim

sql:
select id, name, action from user as u
left join user_action a on
u.id = a.user_id

result:
id | name | action
——————————–
1 | libk | jump ①
1 | libk
| kick ②
1 | libk | jump ③
2 | zyfon | run ④
3 | daodao | null ⑤

分析:
注意到user_action中还有一个user_id=4,
action=swim的纪录,但是没有在结果中出现,
而user表中的id=3,
name=daodao的用户在user_action中没有相应的纪录,但是却出现在了结果集中
因为现在是left
join,所有的工作以left为准.
结果1,2,3,4都是既在左表又在右表的纪录,5是只在左表,不在右表的纪录

结论:
我们可以想象left join
是这样工作的
从左表读出一条,选出所有与on匹配的右表纪录(n条)进行连接,形成n条纪录(包括重复的行,如:结果1和结果3),
如果右边没有与on条件匹配的表,那连接的字段都是null.
然后继续读下一条。

引申:
我们可以用右表没有on匹配则显示null的规律, 来找出所有在左表,不在右表的纪录, 注意用来判断的那列必须声明为not
null的。
如:
sql:
select id, name, action from user as u
left join
user_action a on u.id = a.user_id
where a.user_id is
NULL
(注意:1.列值为null应该用is null 而不能用=NULL
2.这里a.user_id 列必须声明为 NOT NULL
的)
result:
id | name | action
————————–
3 | daodao | NULL

——————————————————————————–

Tips:
1. on a.c1 = b.c1 等同于 using(c1)
2. INNER JOIN 和 , (逗号)
在语义上是等同的
3. 当 MySQL 在从一个表中检索信息时,你可以提示它选择了哪一个索引。
如果 EXPLAIN 显示 MySQL
使用了可能的索引列表中错误的索引,这个特性将是很有用的。
通过指定 USE INDEX (key_list),你可以告诉 MySQL
使用可能的索引中最合适的一个索引在表中查找记录行。
可选的二选一句法 IGNORE INDEX (key_list) 可被用于告诉 MySQL
不使用特定的索引。
4. 一些例子:
mysql> SELECT * FROM table1,table2 WHERE
table1.id=table2.id;
mysql> SELECT * FROM table1 LEFT JOIN table2 ON
table1.id=table2.id;
mysql> SELECT * FROM table1 LEFT JOIN table2 USING
(id);
mysql> SELECT * FROM table1 LEFT JOIN table2 ON
table1.id=table2.id
-> LEFT JOIN table3 ON
table2.id=table3.id;
mysql> SELECT * FROM table1 USE INDEX
(key1,key2)
-> WHERE key1=1 AND key2=2 AND key3=3;
mysql> SELECT *
FROM table1 IGNORE INDEX (key3)
-> WHERE key1=1 AND key2=2 AND key3=3;

7.2.9. MySQL如何优化LEFT JOIN和RIGHT JOIN
在MySQL中,A LEFT JOIN B
join_condition执行过程如下:

· 根据表A和A依赖的所有表设置表B。

· 根据LEFT JOIN条件中使用的所有表(除了B)设置表A。

· LEFT JOIN条件用于确定如何从表B搜索行。(换句话说,不使用WHERE子句中的任何条件)。

· 可以对所有标准联接进行优化,只是只有从它所依赖的所有表读取的表例外。如果出现循环依赖关系,MySQL提示出现一个错误。

· 进行所有标准WHERE优化。

· 如果A中有一行匹配WHERE子句,但B中没有一行匹配ON条件,则生成另一个B行,其中所有列设置为NULL。

· 如果使用LEFT JOIN找出在某些表中不存在的行,并且进行了下面的测试:WHERE部分的col_name IS
NULL,其中col_name是一个声明为 NOT NULL的列,MySQL找到匹配LEFT
JOIN条件的一个行后停止(为具体的关键字组合)搜索其它行。

RIGHT JOIN的执行类似LEFT JOIN,只是表的角色反过来。

联接优化器计算表应联接的顺序。LEFT
JOIN和STRAIGHT_JOIN强制的表读顺序可以帮助联接优化器更快地工作,因为检查的表交换更少。请注意这说明如果执行下面类型的查询,MySQL进行全扫描b,因为LEFT
JOIN强制它在d之前读取:

SELECT *
FROM a,b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d ON
(d.key=a.key)
WHERE b.key=d.key;
在这种情况下修复时用a的相反顺序,b列于FROM子句中:

SELECT *
FROM b,a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d ON
(d.key=a.key)
WHERE b.key=d.key;
MySQL可以进行下面的LEFT
JOIN优化:如果对于产生的NULL行,WHERE条件总为假,LEFT JOIN变为普通联接。

例如,在下面的查询中如果t2.column1为NULL,WHERE 子句将为false:

SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE
t2.column2=5;
因此,可以安全地将查询转换为普通联接:

SELECT * FROM t1, t2 WHERE t2.column2=5 AND
t1.column1=t2.column1;
这样可以更快,因为如果可以使查询更佳,MySQL可以在表t1之前使用表t2。为了强制使用表顺序,使用STRAIGHT_JOIN。

引用自:http://www.phpchina.com/archives/view-33200-1.html

时间: 2024-10-11 10:24:58

MYSQl left join联合查询效率分析的相关文章

mysql中的联合查询(内联、左联、外联、右联、全联)

联合查询效率较高,举例子来说明联合查询:内联inner join .左联left outer join .右联right outer join .全联full outer join 的好处及用法. 联合查询效率较高,以下例子来说明联合查询(内联.左联.右联.全联)的好处: T1表结构(用户名,密码) userid(int) usernamevarchar(20) password varchar(20) 1 jack jackpwd 2 owen owenpwd T2表结构(用户名,密码) us

MySQL多表关联查询效率高点还是多次单表查询效率高,为什么?

MySQL多表关联查询效率高点还是多次单表查询效率高,为什么? <阿里巴巴JAVA开发手册>里面写超过三张表禁止join 这是为什么?这样的话那sql要怎么写? 原文地址:https://www.cnblogs.com/gotodsp/p/10090382.html

mysql中的联合查询

一.基本语法 select 语句1 -- 所有select语句获取的字段数必须一致,与类型无关. union [union选项] -- 与select选项相同, all(全部保留) 和 distinct (去重), 不同的是,默认值为distinct. select 语句2 union...; 二.作用 1. 以不同的需求查询同一张表.如:查询学生信息,男生按年龄升序排序,女生按年龄降序排序. (select * from 表名 where sex = '男' order by age limi

ElasticSearch 使用不同表结构存储时间序列数据的查询效率分析

这里我们使用和之前完全相同的测试数据,来测试 elasticsearch 存储时间序列的表结构选择问题. 一个点一个doc的表结构 同样我们以最简单的表结构开始.在elasticsearch中,先要创建index,然后index下有mapping.所谓的mapping就是表结构的概念.建表的配置如下: settings = {    'number_of_shards': 1,    'number_of_replicas': 0,    'index.query.default_field':

mysql 千万级数据查询效率实践,分析 mysql查询优化实践--本文只做了一部分,仅供参考

数据量, 1300万的表加上112万的表 注意: 本文只做了部分优化,并不全面,仅供参考, 欢迎指点. 请移步tim查看,因为写的时候在tim写的,粘贴过来截图有问题,就直接上链接了. https://823948977.docs.qq.com/T5e6dBYLoZz?opendocxfrom=tim 文章内容类似截图:

mysql使用索引优化查询效率

索引的概念 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针.更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度.在没有索引的情况下,数据库会遍历全部数据后选择符合条件的:而有了相应的索引之后,数据库会直接在索引中查找符合条件的选项.如果我们把SQL语句换成"SELECT * FROM 表名 WHERE id=2000000",那么你是希望数据库按照顺序读取完200万行数据以后给你结果还是直接在索引中定位

解决 mysql多表联合查询时出现的分页问题

mysql一对多分页问题 部门表:tbl_dept 员工表:tbl_emp 数据库sql文件 CREATE DATABASE /*!32312 IF NOT EXISTS*/`ssm-crud` /*!40100 DEFAULT CHARACTER SET utf8 */; USE `ssm-crud`; /*Table structure for table `tbl_dept` */ DROP TABLE IF EXISTS `tbl_dept`; CREATE TABLE `tbl_dep

Sql 分页查询效率分析

选取了2中效率比较高的方式比较效率:row_Number() .offset fetch 表test中有1000条数据,2个字段:field1(int),field2(nvarchar) --1000条数据,查询500次第1-10行,39s --1000条数据,查询500次第500-550行,87s --1000条数据,查询500次第150-160行,88s DECLARE @uId int SET @uId=1 BEGIN while @uId<=500 BEGIN SELECT * FROM

thinkphp3.2使用join联合查询

$members=$model->table('zhope_card A') ->join('zhope_user U ON A.adduser=U.id',"LEFT") ->join('zhope_tpl T ON A.tpl=T.id') ->field('A.id AS I,A.cid AS Card_id,U.name AS Creator,T.name AS Tpl_name') ->select();