MySQL连接语法分析及性能优化
联接用于多个表中字段之间的连接,其语法如下所示:
复制代码代码如下所示:
从表1内|左|右连接表…在条件
表1:左表右表;表。
联接按其功能大致可分为三类:
内部连接(内部连接,或等效连接):获取两个表中连接匹配的记录。
左外连接(左连接):得到左表完整的记录(表1),即右表(表2)没有相应的匹配记录。
右连接(右连接):代替左连接,得到一个完整的右表记录(表2),即左表(表1)不匹配相应的记录。
注意:MySQL不支持完全连接,但可以将左连接和右连接结合起来模拟完全连接。通过联合关键字
接下来我们举一个例子来解释下面的分类。
复制代码代码如下所示:
MySQL >选择张,a.name,B.name从一张,B =数据;
+ -- + + + ----------- -------------
我的名字叫| | | |
+ -- + + + ----------- -------------
| 1 |海盗|大头菜|
| 2 |猴子|海盗|
3 Ninja Darth Vader | | | |
| 4 |意大利面|忍者|
+ -- + + + ----------- -------------
4行(0秒)
二、内部连接
内部连接也称为等效连接,内部连接产生一组符合A和B的数据。
复制代码代码如下所示:
MySQL >选择*从内连接在a.name = b.name;
+——+——+ -------- -------- + +
身份证姓名身份证| | | |名字|
+——+——+ -------- -------- + +
| 1 |海盗| 2 |海盗|
| 3 |忍者| 4 |忍者|
+——+——+ -------- -------- + +
三、左连接
复制代码代码如下所示:
MySQL >选择*从加入B a.name = b.name左;
#:SELECT * FROM左或外连接B a.name = b.name;
+ -- + + + + ----------- ------ --------
身份证姓名身份证| | | |名字|
+ -- + + + + ----------- ------ --------
| 1 |海盗| 2 |海盗|
| 2 |猴子|空|空|
| 3 |忍者| 4 |忍者|
| 4 |意大利面|空|空|
+ -- + + + + ----------- ------ --------
4行(0秒)
左连接,或左外连接:在MySQL中等效。左连接。推荐。左连接从左表(a)和匹配记录(右表(b))生成一组完整的记录。如果没有匹配,右边将包含null。
如果您想从左表(a)中生成一组记录,而不是右表(b)的记录,可以通过设置WHERE语句来执行它,如下所示:
复制代码代码如下所示:
MySQL >选择*从加入B a.name = b.name在A.id左。
+ -- + + + + ----------- ------ ------
身份证姓名身份证| | | |名字|
+ -- + + + + ----------- ------ ------
| 2 |猴子|空|空|
| 4 |意大利面|空|空|
+ -- + + + + ----------- ------ ------
2行(0秒)
同样,我们也可以模拟内部连接。如下:
复制代码代码如下所示:
MySQL >选择*从加入B a.name = b.name在A.id左。
+ -- + + + + -------- ------ --------
身份证姓名身份证| | | |名字|
+ -- + + + + -------- ------ --------
| 1 |海盗| 2 |海盗|
| 3 |忍者| 4 |忍者|
+ -- + + + + -------- ------ --------
2行(0秒)
差集:
根据上面的例子,我们可以找到差异集,如下所示:
复制代码代码如下所示:
SELECT * FROM加入B a.name = b.name左
B.id在那里是空的
联盟
选择*从右加入B a.name = b.name
A.id在那里是空的;
对#结果
+ + + + ------ ----------- ------ ------------- +
身份证姓名身份证| | | |名字|
+ + + + ------ ----------- ------ ------------- +
| 2 |猴子|空|空|
| 4 |意大利面|空|空|
|空|空| 1 |大头菜|
|空|空| 3 |达斯·维德|
+ + + + ------ ----------- ------ ------------- +
四、右连接
复制代码代码如下所示:
MySQL >选择*从右加入B a.name = b.name;
+ + -- + + -------- ------ ------------- +
身份证姓名身份证| | | |名字|
+ + -- + + -------- ------ ------------- +
|空|空| 1 |大头菜|
| 1 |海盗| 2 |海盗|
|空|空| 3 |达斯·维德|
| 3 |忍者| 4 |忍者|
+ + -- + + -------- ------ ------------- +
4行(0秒)
左连接。
五交叉连接
交叉连接:交叉连接,结果是两个表的乘积,即笛卡尔积。
笛卡尔(Descartes)也被称为产品的直接产物。假设集合A = {一},B,和B = {0,1,2},这时两集的笛卡尔积是{(一,0),(一,1),(一,2),(B,0),(B,1),(B,2)},的情况下,可以扩展到多台。类似的例子是,如果一个代表一个学校的学生的集合,B代表在学校所有课程的集合,那么笛卡尔积A和B代表所有可能的选修课程。
复制代码代码如下所示:
从交叉连接b中选择*;
+——+——+ ------------- ----------- + +
身份证姓名身份证| | | |名字|
+——+——+ ------------- ----------- + +
| 1 |海盗| 1 |大头菜|
| 2 |猴子| 1 |大头菜|
| 3 |忍者| 1 |大头菜|
| 4 |意大利面| 1 |大头菜|
| 1 |海盗| 2 |海盗|
| 2 |猴子| 2 |海盗|
| 3 |忍者| 2 |海盗|
| 4 |意大利面| 2 |海盗|
| 1 |海盗| 3 |达斯·维德|
| 2 |猴子| 3 |达斯·维德|
| 3 |忍者| 3 |达斯·维德|
| 4 |意大利面| 3 |达斯·维德|
| 1 |海盗| 4 |忍者|
| 2 |猴子| 4 |忍者|
| 3 |忍者| 4 |忍者|
| 4 |意大利面| 4 |忍者|
+——+——+ ------------- ----------- + +
16行(0秒)
#再次:MySQL >选择*从内连接;尝试
在MySQL >选择# *交叉连接B a.name = b.name实施;尝试
事实上,在MySQL(除MySQL),交叉连接的性能是内部连接一样,其结果是笛卡尔积而不指定条件,否则,两个表的结果是完全matched.inner连接和交叉连接可以忽略内部或跨关键词,所以下面的SQL的影响相同:
复制代码代码如下所示:
从表1内部联接表…
从表1交叉连接表…
从表1和表…
六、完全联接
复制代码代码如下所示:
MySQL >选择*从加入B b.name = a.name左
->联盟
选择*从右连接-> B b.name = a.name;
+ + + + ------ ----------- ------ ------------- +
身份证姓名身份证| | | |名字|
+ + + + ------ ----------- ------ ------------- +
| 1 |海盗| 2 |海盗|
| 2 |猴子|空|空|
| 3 |忍者| 4 |忍者|
| 4 |意大利面|空|空|
|空|空| 1 |大头菜|
|空|空| 3 |达斯·维德|
+ + + + ------ ----------- ------ ------------- +
6行(0秒)
所有连接生成的所有记录(双方匹配记录)都在表A和表B中。如果没有匹配,NULL将包含在相反的方向。
七。性能优化
1。显示(显式)内部连接与隐式(隐式)内部连接
如:
复制代码代码如下所示:
SELECT * FROM
表内部连接表B
在张=数据;
VS
复制代码代码如下所示:
选择A,B,*
从表A,表B
在张=数据;
我比较(10W数据)在数据库中,它们几乎是相同的用的时候,第一个是内部连接的显示,后者是一个隐含的内部联接。
2.left加入/右连接和内连接
尽量避免左连接和null。具有内部连接。
当使用左连接(或右连接)时,您应该清楚地知道以下几点。
(1)。执行顺序
on(条件表达式中的左连接b上的)用于确定如何从B表中检索数据行。如果没有与B表中的on条件匹配的行数据,则会有一列额外的数据列为空。在匹配阶段,将不使用WHERE子句的条件。在匹配阶段完成之后,将使用WHERE子句条件。它将从匹配阶段生成的数据中检索过滤。
所以我们要注意:使用左(右)连接时,必须首先给予尽可能多的满足条件,减少执行的地方:
通过
复制代码代码如下所示:
从中选择*
内连接在b.name = a.name
左连接C c.name = b.name
左连接D d.id =入境
在c.status > 1和d.status = 1;
伟大的
复制代码代码如下所示:
从中选择*
内连接在b.name = a.name
左连接C c.name = b.name和c.status > 1
左连接D d.id =入境和d.status = 1
从上面的例子,我们可以看到,条件的满足,尽可能,和条件的地方少。第二,显然更节省时间从性能表现。
(2)。注意从句和WHERE子句之间的区别。
正如作者举了一个例子:
复制代码代码如下所示:
MySQL >选择*从产品离开加入product_details
在(product.id = product_details。ID)
和product_details id = 2;
+ -- + + + + -------- ------ -------- ------- +
ID身份| | | |重量|存在|
+ -- + + + + -------- ------ -------- ------- +
| 1 | 100 |空|空|空|
| 2 | 200 2 22 0 | | | |
| 3 | 300 |空|空|空|
| 4 | 400 |空|空|空|
+ -- + + + + -------- ------ -------- ------- +
4行(0秒)
MySQL >选择*从产品离开加入product_details
在(product.id = product_details。ID)
在product_details id = 2;
+——+——+ -------- ------- -------- + + +
ID身份| | | |重量|存在|
+——+——+ -------- ------- -------- + + +
| 2 | 200 2 22 0 | | | |
+——+——+ -------- ------- -------- + + +
1行集(0.01秒)
从这个角度来看,第一个查询使用条件来确定所有的数据行,从product_details表在左连接。第二查询作了一个简单的左连接,然后使用WHERE子句来过滤掉非从左边的数据条件的数据线连接。
(3)。尽可能避免使用子查询,使用加入
通常这东西的性能,往往在数据量比较大,我们应该避免复杂的子查询,如下:
通过
复制代码代码如下所示:
从不存在的T2中插入t1(A1)选择B1(选择1);
伟大的
复制代码代码如下所示:
插入t1(A1)
从T2选择B1
左连接(选择不同的t1.id从T1)T1在t1.id = t2.r_id
在t1.id是空的;