当前位置: 移动技术网 > IT编程>数据库>Mysql > MySQL中join语句的基本使用教程及其字段对性能的影响

MySQL中join语句的基本使用教程及其字段对性能的影响

2017年12月12日  | 移动技术网IT编程  | 我要评论

蛋黄酱沙拉酱,协和创美,大闹广昌隆粤语版

join语句的基本使用

sql(mysql) join 用于根据两个或多个表中的字段之间的关系,从这些表中得到数据。

join 通常与 on 关键字搭配使用,基本语法如下:

... from table1 inner|left|right join table2 on conditiona
table1 通常称为左表,table2 称为右表。on 关键字用于设定匹配条件,用于限定在结果集合中想要哪些行。如果需要指定其他条件,后面可以加上 where 条件 或者 limit 以限制记录返回数目等。

下面以最常见的两表连接来说明 mysql join 的用法,关于多表 join 请参见《mysql join 多表》。

mysql join 分类

join 按照功能大致分为如下三类:

  1. inner join(内连接):取得两个表中存在连接匹配关系的记录。
  2. left join(左连接):取得左表(table1)完全记录,即是右表(table2)并无对应匹配记录。
  3. right join(右连接):与 left join 相反,取得右表(table2)完全记录,即是左表(table1)并无匹配对应记录。

关于 mysql full join 全连接

mysql 没有提供 sql 标准中的 full join(全连接):两个表记录都取出,而不管彼此是否有对应记录。要解决此问题,可以使用 union 关键字来合并 left join 与 right join,达到模拟 full join 的目的。

mysql inner join

inner join 用于取得两个表中存在连接匹配关系的记录。下面是两个原始数据表:

20151216104417019.png (366×317)

article 表中文章的所属用户是通过 uid 这个字段与 user 表关联起来的。通过观察数据不难发现,对于 uid=3 的用户,并没有发表任何文章;而文章中 aid=4 却无法在 uid 表中找到对应记录(可能是该用户被删除而其所属的文章却被保留了下来)。

我们列出所用文章与用户一一对应的数据。

select … inner join … on 语句如下:

select article.aid,article.title,user.username from article inner join user on article.uid = user.uid

返回查询结果如下:

20151216104447947.png (273×126)

对于 inner join,等同与下面的 sql 语句:

select article.aid,article.title,user.username from article,user where article.uid = user.uid

cross join

cross join 即交叉连接,在不指定 on 条件下:

select article.aid,article.title,user.username from article cross join user

得到的结果是被连接的两个数据表的乘积,即笛卡尔积。

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

inner join 与 cross join 可以省略 inner 或 cross 关键字,因此下面的 sql 效果是一样的:

平板视图打印?

... from table1 inner join table2

... from table1 cross join table2

... from table1 join table2


join的字段字符集编码对性能的影响

先来看一下示例代码:

建utf-8编码的表 t1:

create table if not exists `t1` (
 `name` varchar(50) not null default '',
 key `name` (`name`)
) engine=myisam default charset=utf8;

随便插入些数据,数量大一点,后面实验结果更清晰,偷个懒,构造随机字符串插入语句

insert into t1(name) 
select concat(
char(round((rand())*25)+97),
char(round((rand())*25)+65),
char(round((rand())*25)+65),
char(round((rand())*25)+97),
char(round((rand())*25)+65),
char(round((rand())*25)+65),
char(round((rand())*25)+97),
char(round((rand())*25)+65)
)

每次执行插入一条记录,用你熟悉的脚本(python,php,shell等都行)写个循环,执行一万次以上。

将该表复制成一个新表t2,删除一部分数据,1000条左右即可。(推荐使用phpmyadmin)

再将t2复制为t3,并将字段改为gb2312编码。

使用一个left join语句,写一个语句,查出t2/t3比t1少了哪些记录。

语句很简单,如下:

select sql_no_cache t1.name, t2.name
from t1
left join t2 on t1.name = t2.name
where t2.name is null 
limit 0 , 30

注意加入 sql_no_cache ,禁用mysql缓存。

先看编码一致的t2表,phpmyadmin里执行结果:

显示行 0 - 29 ( 1,129 总计, 查询花费 0.0010 秒)
平均耗时大概为0.0010秒

select sql_no_cache t1.name, t3.name
from t1
left join t3 on t1.name = t3.name
where t2.name is null 
limit 0 , 30

phpmyadmin执行结果:

显示行 0 - 29 ( 30 总计, 查询花费 0.1871 秒)
差两个数量级!

查询语句解释:

20151216104614308.png (697×497)

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网