MYSQL中JOIN的用法

近期用phpcms v9作项目,初期没有问题,后期随着数据量的增大,phpcms v9后台出现的栏目更新不动的状况,初期我觉得是程序的问题,进行了程序排查,没有发现任何问题,登陆上centos服务器后free命令发现内存也没有满。瞬间感受很蛋疼,不知如何处理,后来登陆阿里云帐号,发现更新栏目时,cpu使用率直接到达100%,xhell远程登陆进入服务器后用top检测cpu使用率的状况,发现MySQL占用的cpu使用率的100%,直接登陆进入MySQL数据库,输入show full processlist; 能够看到正在执行的语句。看到是一条嵌套的sql语句执行异常缓慢!因为作项目以前没有考虑到数据量的问题,因此出现这样的状况,想比较嵌套的sql语句,关联查询性能效率会高不少,多表关联查询有一个关键的词就是join。php

JOIN的含义就如英文单词“join”同样,链接两张表,大体分为内链接,外链接,右链接,左链接,天然链接。这里描述先甩出一张用烂了的图,而后插入测试数据。html

 

  View Code

笛卡尔积:CROSS JOIN

要理解各类JOIN首先要理解笛卡尔积。笛卡尔积就是将A表的每一条记录与B表的每一条记录强行拼在一块儿。因此,若是A表有n条记录,B表有m条记录,笛卡尔积产生的结果就会产生n*m条记录。下面的例子,t_blog有10条记录,t_type有5条记录,全部他们俩的笛卡尔积有50条记录。有五种产生笛卡尔积的方式以下。sql

  View Code

内链接:INNER JOIN

内链接INNER JOIN是最经常使用的链接操做。从数学的角度讲就是求两个表的交集,从笛卡尔积的角度讲就是从笛卡尔积中挑出ON子句条件成立的记录。有INNER JOIN,WHERE(等值链接),STRAIGHT_JOIN,JOIN(省略INNER)四种写法。至于哪一种好我会在MySQL的JOIN(二):优化讲述。示例以下。数据库

复制代码
复制代码
    SELECT * FROM t_blog INNER JOIN t_type ON t_blog.typeId=t_type.id;
    SELECT * FROM t_blog,t_type WHERE t_blog.typeId=t_type.id;
    SELECT * FROM t_blog STRAIGHT_JOIN t_type ON t_blog.typeId=t_type.id; --注意STRIGHT_JOIN有个下划线
    SELECT * FROM t_blog JOIN t_type ON t_blog.typeId=t_type.id;
+----+-------+--------+----+------+ | id | title | typeId | id | name | +----+-------+--------+----+------+ | 1 | aaa | 1 | 1 | C++ | | 2 | bbb | 2 | 2 | C | | 7 | ggg | 2 | 2 | C | | 3 | ccc | 3 | 3 | Java | | 6 | fff | 3 | 3 | Java | | 4 | ddd | 4 | 4 | C# | | 5 | eee | 4 | 4 | C# | +----+-------+--------+----+------+
复制代码
复制代码

 

左链接:LEFT JOIN

左链接LEFT JOIN的含义就是求两个表的交集外加左表剩下的数据。依旧从笛卡尔积的角度讲,就是先从笛卡尔积中挑出ON子句条件成立的记录,而后加上左表中剩余的记录(见最后三条)。centos

复制代码
复制代码
    SELECT * FROM t_blog LEFT JOIN t_type ON t_blog.typeId=t_type.id;
+----+-------+--------+------+------+ | id | title | typeId | id | name | +----+-------+--------+------+------+ | 1 | aaa | 1 | 1 | C++ | | 2 | bbb | 2 | 2 | C | | 7 | ggg | 2 | 2 | C | | 3 | ccc | 3 | 3 | Java | | 6 | fff | 3 | 3 | Java | | 4 | ddd | 4 | 4 | C# | | 5 | eee | 4 | 4 | C# | | 8 | hhh | NULL | NULL | NULL | | 9 | iii | NULL | NULL | NULL | | 10 | jjj | NULL | NULL | NULL | +----+-------+--------+------+------+
复制代码
复制代码

 

右链接:RIGHT JOIN

同理右链接RIGHT JOIN就是求两个表的交集外加右表剩下的数据。再次从笛卡尔积的角度描述,右链接就是从笛卡尔积中挑出ON子句条件成立的记录,而后加上右表中剩余的记录(见最后一条)。服务器

复制代码
复制代码
    SELECT * FROM t_blog RIGHT JOIN t_type ON t_blog.typeId=t_type.id;
+------+-------+--------+----+------------+ | id | title | typeId | id | name | +------+-------+--------+----+------------+ | 1 | aaa | 1 | 1 | C++ | | 2 | bbb | 2 | 2 | C | | 3 | ccc | 3 | 3 | Java | | 4 | ddd | 4 | 4 | C# | | 5 | eee | 4 | 4 | C# | | 6 | fff | 3 | 3 | Java | | 7 | ggg | 2 | 2 | C | | NULL | NULL | NULL | 5 | Javascript | +------+-------+--------+----+------------+
复制代码
复制代码

外链接:OUTER JOIN

外链接就是求两个集合的并集。从笛卡尔积的角度讲就是从笛卡尔积中挑出ON子句条件成立的记录,而后加上左表中剩余的记录,最后加上右表中剩余的记录。另外MySQL不支持OUTER JOIN,可是咱们能够对左链接和右链接的结果作UNION操做来实现。性能

复制代码
复制代码
    SELECT * FROM t_blog LEFT JOIN t_type ON t_blog.typeId=t_type.id
    UNION
    SELECT * FROM t_blog RIGHT JOIN t_type ON t_blog.typeId=t_type.id;
+------+-------+--------+------+------------+ | id | title | typeId | id | name | +------+-------+--------+------+------------+ | 1 | aaa | 1 | 1 | C++ | | 2 | bbb | 2 | 2 | C | | 7 | ggg | 2 | 2 | C | | 3 | ccc | 3 | 3 | Java | | 6 | fff | 3 | 3 | Java | | 4 | ddd | 4 | 4 | C# | | 5 | eee | 4 | 4 | C# | | 8 | hhh | NULL | NULL | NULL | | 9 | iii | NULL | NULL | NULL | | 10 | jjj | NULL | NULL | NULL | | NULL | NULL | NULL | 5 | Javascript | +------+-------+--------+------+------------+
复制代码
复制代码

USING子句

MySQL中链接SQL语句中,ON子句的语法格式为:table1.column_name = table2.column_name。当模式设计对联接表的列采用了相同的命名样式时,就能够使用 USING 语法来简化 ON 语法,格式为:USING(column_name)。 
因此,USING的功能至关于ON,区别在于USING指定一个属性名用于链接两个表,而ON指定一个条件。另外,SELECT *时,USING会去除USING指定的列,而ON不会。实例以下。测试

复制代码
复制代码
    SELECT * FROM t_blog INNER JOIN t_type ON t_blog.typeId =t_type.id;
    +----+-------+--------+----+------+
    | id | title | typeId | id | name |
    +----+-------+--------+----+------+
    |  1 | aaa   |      1 |  1 | C++  |
    |  2 | bbb   |      2 |  2 | C    |
    |  7 | ggg   |      2 |  2 | C    |
    |  3 | ccc   |      3 |  3 | Java |
    |  6 | fff   |      3 |  3 | Java |
    |  4 | ddd   |      4 |  4 | C#   |
    |  5 | eee   |      4 |  4 | C#   |
    +----+-------+--------+----+------+

SELECT * FROM t_blog INNER JOIN t_type USING(typeId); ERROR 1054 (42S22): Unknown column 'typeId' in 'from clause' SELECT * FROM t_blog INNER JOIN t_type USING(id); -- 应为t_blog的typeId与t_type的id不一样名,没法用Using,这里用id代替下。 +----+-------+--------+------------+ | id | title | typeId | name | +----+-------+--------+------------+ | 1 | aaa | 1 | C++ | | 2 | bbb | 2 | C | | 3 | ccc | 3 | Java | | 4 | ddd | 4 | C# | | 5 | eee | 4 | Javascript | +----+-------+--------+------------+
复制代码
复制代码

文章源自贝利-园子

相关文章
相关标签/搜索