3. www.2345.com
SELECT查询预览
SELECT DISTINCT <select_list>
FROM <left_table>
<join_type> JOIN <right_table>
ON <join_condition>
WHERE <where_condition>
GROUP BY <group_by_list>
WITH{CUBE|ROLLUP}
HAVING <having_condition>
ORDER BY <order_by_list>
LIMIT <limit_number>
4. www.2345.com
SELECT 逻辑处理概览:
(8) SELECT (9) DISTINCT <select_list>
(1) FROM <left_table>
(3 ) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH{CUBE|ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY <order_by_list>
(11) LIMIT <limit_number>
11个步骤,最先执行
的是FROM操作,最
后执行的是LIMIT操
作。每个操作都会产
生一张虚拟表,以下
记为“VTn”该虚拟表
作为一个处理的输入
5. www.2345.com
第一组FROM、ON:
(8) SELECT (9) DISTINCT <select_list>
(1) FROM <left_table>
(3 ) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH{CUBE|ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY < order_by_list >
(11) LIMIT <limit_number>
对FROM子句中的左表
<left_table>和右表
<right_table>执行笛卡儿
积(Cartesian product),
产生虚拟表VT1
对虚拟表VT1应用ON筛选,
只有符合<join_condition>的
行才被插入虚拟表VT2中
6. www.2345.com
承前启后的join:
(8) SELECT (9) DISTINCT <select_list>
(1) FROM <left_table>
(3 ) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH{CUBE|ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY < order_by_list >
(11) LIMIT <limit_number>
如果指定了OUTER JOIN
(如LEFT OUTER JOIN、
RIGHT OUTER JOIN),那
么保留表中未匹配的行作为
外部行添加到虚拟表VT2中,
产生虚拟表VT3。如果
FROM子句包含两个以上表,
则对上一个连接生成的结果
表VT3和下一个表重复执行
步骤1)~步骤3),直到
处理完所有的表为止。
7. www.2345.com
Where你需要什么:
(8) SELECT (9) DISTINCT <select_list>
(1) FROM <left_table>
(3 ) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH{CUBE|ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY <having_condition>
(11) LIMIT <limit_number>
对虚拟表VT3应用
WHERE过滤条件,只有
符合<where_condition>
的记录才被插入虚拟表
VT4中
8. www.2345.com
GROUP BY:
(8) SELECT (9) DISTINCT <select_list>
(1) FROM <left_table>
(3 ) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH{CUBE|ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY < order_by_list >
(11) LIMIT <limit_number>
根据GROUP BY子句中
的列,对VT4中的记录
进行分组操作,产生
VT5
如果有对表VT5
进行CUBE或
ROLLUP操作,
产生表VT6
9. www.2345.com
组内过滤HAVING:
(8) SELECT (9) DISTINCT <select_list>
(1) FROM <left_table>
(3 ) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH{CUBE|ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY < order_by_list >
(11) LIMIT <limit_number>
对虚拟表VT6应
用HAVING过滤器,只
有符合
<having_condition>
的记录才被插入虚拟
表VT7中
10. www.2345.com
选择去重:
(8) SELECT (9) DISTINCT <select_list>
(1) FROM <left_table>
(3 ) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH{CUBE|ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY <having_condition>
(11) LIMIT <limit_number>
把重复的行从
VT8中删除,插
入VT9
执行SELECT操作,
选择指定的列,插
入到虚拟表VT8中
11. www.2345.com
排序,返回结果:
(8) SELECT (9) DISTINCT <select_list>
(1) FROM <left_table>
(3 ) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group _by_list>
(6) WITH{CUBE|ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY <having_condition>
(11) LIMIT <limit_number>
将虚拟表VT9中的记录
按照<order_by_list>进
行排序操作,产生虚拟
表VT10
取出指定行的记录,
产生虚拟表VT11,并
返回给查询用户
12. www.2345.com
查询总结…
(8) SELECT (9) DISTINCT <select_list>
(1) FROM <left_table>
(3 ) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH{CUBE|ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY < order_by_list >
(11) LIMIT <limit_number>
Join表生成笛卡尔积vt1
On条件过滤vt1插入到vt2
join未匹配的外部行插入得vt3
Where过滤vt3得vt4
分组vt4得出vt5
13. www.2345.com
…查询总结
(8) SELECT (9) DISTINCT <select_list>
(1) FROM <left_table>
(3 ) <join_type> JOIN <right_table>
(2) ON <join_condition>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) WITH{CUBE|ROLLUP}
(7) HAVING <having_condition>
(10) ORDER BY < order_by_list >
(11) LIMIT <limit_number>
Vt7排序后插入vt8
从vt8选择所需列得vt9
有distinct删除重复行插入vt10
取出vt10指定行插入vt11
并返回给用户
Having条件对vt6过滤得vt7
rollup对vt5汇总得vt6
(CUBE mysql 还未实现)
17. www.2345.com
Where中的查询条件提取…
实例一插入数据
root@localhost: test >insert into test select 4,3,1,1,'d';
root@localhost: test >insert into test select 1,1,1,1,'a';
root@localhost: test >insert into test select 9,9,9,9,'t';
root@localhost: test >insert into test select 2,2,2,2,'b';
root@localhost: test >insert into test select 5,2,3,5,'e';
root@localhost: test >insert into test select 3,3,2,2,'v';
root@localhost: test >insert into test select 7,4,5,5,'g';
root@localhost: test >insert into test select 6,6,4,4,'f';
19. www.2345.com
Where中的查询条件提取…
SQL的where条件提取
select * from test where b >= 2 and b < 9 and c > 1 and d != 4 and e != 'a';
结合图一索引思考此查询语句:where条件使用到了
[b,c,d,e]四个字段,而test表的idx_b_c_d索引,恰好使用
了[b,c,d]这三个字段,
那么走idx_b_c_d索引进行条件过滤成为可能
20. www.2345.com
Where中的查询条件提取…
索引范围检查
select * from test where b >= 2 and b < 9 and c > 1 and d != 4 and e != 'a';
起始范围:记录[2,2,2]是第一个
需要检查的索引项。索引起始查
找范围由b >= 2,c > 1决定。
终止范围:记录[9,9,9]是第一个
不需要检查的记录,而之前的记
录均需要判断。索引的终止查找
范围由b < 9决定;
21. www.2345.com
Where中的查询条件提取…
索引范围检查
select * from test where b >= 2 and b < 9 and c > 1 and d != 4 and e != 'a';
固定了索引的查询范围
[(2,2,2),(9,9,9))之后,此索引范围中
并不是每条记录都是满足where查询
条件,例如:(3,1,1)不满足c > 1,
(6,4,4)不满足d != 4的约束。而c,d
列,均可在索引idx_b_c_d中过滤掉不
满足条件的索引记录。
因此,SQL中还可以使用c > 1 and
d != 4条件进行索引记录的过滤
22. www.2345.com
Where中的查询条件提取…
索引范围外检查
select * from test where b >= 2 and b < 9 and c > 1 and d != 4 and e != 'a';
可见,e != ‘a’这个查询条件,无法
在索引idx_a_b_c上进行过滤,因
为索引不包含e列,e列只在堆表
上存在,
为了过滤此查询条件,必须将已
经满足索引查询条件的记录回表,
取出表中的e列,然后使用e列的
查询条件e != ‘a’进行最终的过滤
4
3
1
1
d
1
1
1
1
a
9
9
9
9
t
2
2
2
2
b
5
2
3
5
e
3
3
2
2
v
7
4
5
5
g
6
6
4
4
f
堆表