上面的查询进程切合语义,可是假如在filter前提能过滤很大都据的时辰,先举办数据的过滤,在举办内联接会获取更好的机能,好比我们手工写一下:
- mysql> SELECT
- -> no, name , score
- -> FROM student stu JOIN ( SELECT s_no, score FROM score s WHERE s.score >80) as sc ON no = s_no;
- +------+-------+-------+
- | no | name | score |
- +------+-------+-------+
- | S001 | Sunny | 98 |
- | S003 | Kevin | 88 |
- +------+-------+-------+
- 2 rows in set (0.00 sec)
上面写法语义和第一种写法语义同等,获得沟通的查询功效,上面查询进程是:
- mysql> SELECT s_no, score FROM score s WHERE s.score >80;
- +------+-------+
- | s_no | score |
- +------+-------+
- | S001 | 98 |
- | S003 | 88 |
- +------+-------+
- 2 rows in set (0.00 sec)
第二步:执行内毗连
- -> ON no = s_no;
- +------+-------+-------+
- | no | name | score |
- +------+-------+-------+
- | S001 | Sunny | 98 |
- | S003 | Kevin | 88 |
- +------+-------+-------+
- 2 rows in set (0.00 sec)
如上两种写法在语义上同等,但查询机能在数目很大的环境下会有很大差距。上面为了和各人演示沟通的查询语义,可以有差异的查询方法,差异的执行打算。现实上数据库自己的优化器会自动举办查询优化,在内联接中ON的联接前提和WHERE的过滤前提具有沟通的优先级,,详细的执行次序可以由数据库的优化器按照机能耗损抉择。也就是说物理执行打算可以先执行过滤前提举办查询优化,假如仔细的读者也许发明,在第二个写法中,子查询我们不单有行的过滤,也举办了列的裁剪(去除了对查询功效没有效的c_no列),这两个变革现实上对应了数据库中两个优化法则:
- filter push down
- project push down
如上优化法则以filter push down 为例,表示优化器对执行plan的优化变换:

3. LEFT OUTER JOIN
左外联接语义是返回左表全部行,右表不存在补NULL,为了演示浸染,我们查询没有介入测验的全部门生的后果单:
- mysql> SELECT
- -> no, name , s.c_no, s.score
- -> FROM student stu LEFT JOIN score s ON sstu.no = s.s_no
- -> WHERE s.score is NULL;
- +------+------+------+-------+
- | no | name | c_no | score |
- +------+------+------+-------+
- | S002 | Tom | NULL | NULL |
- +------+------+------+-------+
- 1 row in set (0.00 sec)
上面查询的执行逻辑上也是分成两步:
- mysql> SELECT
- -> no, name , s.c_no, s.score
- -> FROM student stu LEFT JOIN score s ON sstu.no = s.s_no;
- +------+-------+------+-------+
- | no | name | c_no | score |
- +------+-------+------+-------+
- | S001 | Sunny | C01 | 80 |
- | S001 | Sunny | C02 | 98 |
- | S001 | Sunny | C03 | 76 |
- | S002 | Tom | NULL | NULL | -- 右表不存在的补NULL
- | S003 | Kevin | C01 | 78 |
- | S003 | Kevin | C02 | 88 |
- | S003 | Kevin | C03 | 68 |
- +------+-------+------+-------+
- 7 rows in set (0.00 sec)
第二步:过滤查询
- mysql> SELECT
- -> no, name , s.c_no, s.score
- -> FROM student stu LEFT JOIN score s ON sstu.no = s.s_no
- -> WHERE s.score is NULL;
- +------+------+------+-------+
- | no | name | c_no | score |
- +------+------+------+-------+
- | S002 | Tom | NULL | NULL |
- +------+------+------+-------+
- 1 row in set (0.00 sec)
(编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|