一.查询的执行路径
一条SQL查询语句的执行过程大致如下图所示:
1>.客户端和服务端通过mysql协议进行通信,mysql服务器通过某种客户端发送来的查询语句的时候,首先会去本地检验缓存是否命中,如果请求的SQL语句之前有本查询过,就会把之前的查询结果直接返回给用户(查询缓存的功能最少要满足三成以上才有意义,如果所有的查询都去用缓存且所有的SQL没有一次被命中的话就毫无意义啦。);
2>.如果查询的SQL没有命中,就会将SQL的请求交给解析器进行解析操作。必要时在预处理器的配合下,解析器会生成一个解析树,这个解析树会有很多条执行路径去查询我们想要得到的SQL结果;
3>.如此多的执行路径就会交给查询优化器进行查询操作,查询优化器会选择资源开销最少的路径去执行SQL语句,与此同时,它还可能改写SQL语句,只要改写的结果和用户要查询的结果一致即可,查询优化器选择最优的一条执行路径之后又将这个结果交给查询执行计划进行排队(注意,MySQL的用户同时查询可能不止一个,因此并发的时候需要给它一个队列,哪些查询比较先进的会优先被查询到返回给用户);
4>.以上的所有操作都没有执行的权限,最终执行查询操作的还是查询执行引擎。但是查询引擎并不能直接到磁盘上取数据,查询引擎本事只是把查询请求转换成对应表的存储引擎的API调用;
5>.我们知道存储引擎其实是表类型,存储引擎根据查询执行引擎的API调用从磁盘上获取对方所需要的数据并层层返回给用户,在返回的途中,mysql还要考虑是否将查询结果进行缓存操作。
二.选择和投影
1.投影和选择
投影其实就是挑选要符合的字段,选择就是挑选符合条件的行。
投影:select 字段1,字段2,... from tb_name;
常用语法格式:selcet * from tb_name;
选择:select 字段1,字段2,.... from tb_name where 子句(布尔条件表达式);
2.布尔条件表达式操作符
= 等值比较
<=>:跟空值比较不会产生额外信息
<>:不等值
<:
<=
>
>=
IS NULL:是否为空
IS NOT NULL:是否不空
LIKE:支持的通配符%(任意长度的任意字符) _(任意单个字符)
RLIKE,REGEXP:支持使用正则表达式作为条件(注意LIKE和RLIKE都是用来做字符比较的,如果用来做数值比较的话性能就相当低了。)
IN:判断某行的某一字段的值是否在给定的列表中
BETWEEN...AND....:判断指定的值是否位于指定的范围之间(比如,判断一个数值在10和20之间,我们就可以这样写"X BETWEEN 10 AND 20")
案例展示:
mysql> use yanhuihuang Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> create table stars(SID int unsigned auto_increment not null unique key,Name char(50) not null,Age tinyint unsigned not null,Gender Enum('boy','girl') not null, Tearch char(50)); Query OK, 0 rows affected (0.01 sec) mysql> desc stars; +--------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------+---------------------+------+-----+---------+----------------+ | SID | int(10) unsigned | NO | PRI | NULL | auto_increment | | Name | char(50) | NO | | NULL | | | Age | tinyint(3) unsigned | NO | | NULL | | | Gender | enum('boy','girl') | NO | | NULL | | | Tearch | char(50) | YES | | NULL | | +--------+---------------------+------+-----+---------+----------------+ 5 rows in set (0.00 sec) mysql> insert into stars values (1,"zhangsan",27,'boy','sunwokong'),(2,'lisi',26,'boy','zhubajie'),(3,'wanwu',21,'boy','shaseng'); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> insert into stars values (4,"zhaoliu",17,'boy','yudi'),(5,'qianqi',16,'boy','wanmu'),(6,'yanba',21,'boy','change'); Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from stars; +-----+----------+-----+--------+-----------+ | SID | Name | Age | Gender | Tearch | +-----+----------+-----+--------+-----------+ | 1 | zhangsan | 27 | boy | sunwokong | | 2 | lisi | 26 | boy | zhubajie | | 3 | wanwu | 21 | boy | shaseng | | 4 | zhaoliu | 17 | boy | yudi | | 5 | qianqi | 16 | boy | wanmu | | 6 | yanba | 21 | boy | change | +-----+----------+-----+--------+-----------+ 6 rows in set (0.00 sec) mysql> select * from stars where Age between 16 and 20; +-----+---------+-----+--------+--------+ | SID | Name | Age | Gender | Tearch | +-----+---------+-----+--------+--------+ | 4 | zhaoliu | 17 | boy | yudi | | 5 | qianqi | 16 | boy | wanmu | +-----+---------+-----+--------+--------+ 2 rows in set (0.00 sec) mysql> select Name,Age from stars where Age in (18,21); +-------+-----+ | Name | Age | +-------+-----+ | wanwu | 21 | | yanba | 21 | +-------+-----+ 2 rows in set (0.00 sec) mysql> select Name,Age from stars where Name rlike '^y.*'; +-------+-----+ | Name | Age | +-------+-----+ | yanba | 21 | +-------+-----+ 1 row in set (0.00 sec) mysql> insert into stars values(7,'chenshi',11,'girl','erlangsheng'),(8,'liuer',14,'boy',NULL); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> select * from stars; +-----+----------+-----+--------+-------------+ | SID | Name | Age | Gender | Tearch | +-----+----------+-----+--------+-------------+ | 1 | zhangsan | 27 | boy | sunwokong | | 2 | lisi | 26 | boy | zhubajie | | 3 | wanwu | 21 | boy | shaseng | | 4 | zhaoliu | 17 | boy | yudi | | 5 | qianqi | 16 | boy | wanmu | | 6 | yanba | 21 | boy | change | | 7 | chenshi | 11 | girl | erlangsheng | | 8 | liuer | 14 | boy | NULL | +-----+----------+-----+--------+-------------+ 8 rows in set (0.00 sec) mysql> select Name,Tearch from stars where Tearch is NULL; +-------+--------+ | Name | Tearch | +-------+--------+ | liuer | NULL | +-------+--------+ 1 row in set (0.00 sec) mysql> select Name,Tearch from stars where Tearch is NOT NULL; +----------+-------------+ | Name | Tearch | +----------+-------------+ | zhangsan | sunwokong | | lisi | zhubajie | | wanwu | shaseng | | zhaoliu | yudi | | qianqi | wanmu | | yanba | change | | chenshi | erlangsheng | +----------+-------------+ 7 rows in set (0.00 sec)
3.组合条件测试
NOT !
AND &&
OR ||
案例展示:
mysql> select database(); +-------------+ | database() | +-------------+ | yanhuihuang | +-------------+ 1 row in set (0.00 sec) mysql> show tables; +-----------------------+ | Tables_in_yanhuihuang | +-----------------------+ | stars | | t1 | +-----------------------+ 2 rows in set (0.00 sec) mysql> select * from stars; +-----+----------+-----+--------+-------------+ | SID | Name | Age | Gender | Tearch | +-----+----------+-----+--------+-------------+ | 1 | zhangsan | 27 | boy | sunwokong | | 2 | lisi | 26 | boy | zhubajie | | 3 | wanwu | 21 | boy | shaseng | | 4 | zhaoliu | 17 | boy | yudi | | 5 | qianqi | 16 | boy | wanmu | | 6 | yanba | 21 | boy | change | | 7 | chenshi | 11 | girl | erlangsheng | | 8 | liuer | 14 | boy | NULL | +-----+----------+-----+--------+-------------+ 8 rows in set (0.00 sec) mysql> select Name,Age from stars where Age > 16 and Gender = 'boy'; +----------+-----+ | Name | Age | +----------+-----+ | zhangsan | 27 | | lisi | 26 | | wanwu | 21 | | zhaoliu | 17 | | yanba | 21 | +----------+-----+ 5 rows in set (0.00 sec)
4.排序
order by ‘排序字段’
默认为升序:ASC
降序:DESC
案例展示:
mysql> select * from stars; +-----+----------+-----+--------+-------------+ | SID | Name | Age | Gender | Tearch | +-----+----------+-----+--------+-------------+ | 1 | zhangsan | 27 | boy | sunwokong | | 2 | lisi | 26 | boy | zhubajie | | 3 | wanwu | 21 | boy | shaseng | | 4 | zhaoliu | 17 | boy | yudi | | 5 | qianqi | 16 | boy | wanmu | | 6 | yanba | 21 | boy | change | | 7 | chenshi | 11 | girl | erlangsheng | | 8 | liuer | 14 | boy | NULL | +-----+----------+-----+--------+-------------+ 8 rows in set (0.00 sec) mysql> select Name,Age from stars where Age > 16 and Gender = 'boy' order by Name desc; +----------+-----+ | Name | Age | +----------+-----+ | zhaoliu | 17 | | zhangsan | 27 | | yanba | 21 | | wanwu | 21 | | lisi | 26 | +----------+-----+ 5 rows in set (0.00 sec) mysql> select Name,Age from stars where Age > 16 and Gender = 'boy' order by Name asc; +----------+-----+ | Name | Age | +----------+-----+ | lisi | 26 | | wanwu | 21 | | yanba | 21 | | zhangsan | 27 | | zhaoliu | 17 | +----------+-----+ 5 rows in set (0.00 sec)
5.常用内置的聚合函数
关键字如下:
1>.SUM():运算和
2>.AVG():运算平均值
3>.MAX():运算最大值
5>.MIN():运算最小值
6>.COUNT():运算个数统计
案例展示:
mysql> select SUM(Age) from stars; +----------+ | SUM(Age) | +----------+ | 153 | +----------+ 1 row in set (0.01 sec) mysql> select MIN(Age) from stars; +----------+ | MIN(Age) | +----------+ | 11 | +----------+ 1 row in set (0.00 sec) mysql> select MAX(Age) from stars; +----------+ | MAX(Age) | +----------+ | 27 | +----------+ 1 row in set (0.00 sec) mysql> select COUNT(*) from stars; +----------+ | COUNT(*) | +----------+ | 8 | +----------+ 1 row in set (0.00 sec) mysql> select SUM(Age) from stars where Age > 21; +----------+ | SUM(Age) | +----------+ | 53 | +----------+ 1 row in set (0.00 sec)
6.分组
关键字:group by
案例展示:
mysql> select * from stars; +-----+----------+-----+--------+-------------+ | SID | Name | Age | Gender | Tearch | +-----+----------+-----+--------+-------------+ | 1 | zhangsan | 27 | boy | sunwokong | | 2 | lisi | 26 | boy | zhubajie | | 3 | wanwu | 21 | boy | shaseng | | 4 | zhaoliu | 17 | boy | yudi | | 5 | qianqi | 16 | boy | wanmu | | 6 | yanba | 21 | boy | change | | 7 | chenshi | 11 | girl | erlangsheng | | 8 | liuer | 14 | boy | NULL | +-----+----------+-----+--------+-------------+ 8 rows in set (0.00 sec) mysql> select Gender,SUM(Age) from stars group by Gender; +--------+----------+ | Gender | SUM(Age) | +--------+----------+ | boy | 142 | | girl | 11 | +--------+----------+ 2 rows in set (0.01 sec)
7.对分组的条件过滤
关键字:having
案例展示:
mysql> select * from stars; +-----+----------+-----+--------+-------------+---------+ | SID | Name | Age | Gender | Tearch | ClassID | +-----+----------+-----+--------+-------------+---------+ | 1 | zhangsan | 27 | boy | sunwokong | NULL | | 2 | lisi | 26 | boy | zhubajie | NULL | | 3 | wanwu | 21 | boy | shaseng | NULL | | 4 | zhaoliu | 17 | boy | yudi | NULL | | 5 | qianqi | 16 | boy | wanmu | NULL | | 6 | yanba | 21 | boy | change | NULL | | 7 | chenshi | 11 | girl | erlangsheng | NULL | | 8 | liuer | 14 | boy | NULL | NULL | +-----+----------+-----+--------+-------------+---------+ 8 rows in set (0.00 sec) mysql> update stars set ClassID = 3 where SID =2 ; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> update stars set ClassID = 5 where SID = 3 ; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> update stars set ClassID = 1 where SID = 1 ; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> update stars set ClassID = 2 where SID = 4 ; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> update stars set ClassID = 4 where SID = 5 ; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> update stars set ClassID = 2 where SID = 6 ; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> update stars set ClassID = 3 where SID = 7 ; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> update stars set ClassID = 2 where SID = 8 ; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from stars; +-----+----------+-----+--------+-------------+---------+ | SID | Name | Age | Gender | Tearch | ClassID | +-----+----------+-----+--------+-------------+---------+ | 1 | zhangsan | 27 | boy | sunwokong | 1 | | 2 | lisi | 26 | boy | zhubajie | 3 | | 3 | wanwu | 21 | boy | shaseng | 5 | | 4 | zhaoliu | 17 | boy | yudi | 2 | | 5 | qianqi | 16 | boy | wanmu | 4 | | 6 | yanba | 21 | boy | change | 2 | | 7 | chenshi | 11 | girl | erlangsheng | 3 | | 8 | liuer | 14 | boy | NULL | 2 | +-----+----------+-----+--------+-------------+---------+ 8 rows in set (0.00 sec) mysql> select ClassID,Count(Name),sum(Age) from stars group by ClassID; +---------+-------------+----------+ | ClassID | Count(Name) | sum(Age) | +---------+-------------+----------+ | 1 | 1 | 27 | | 2 | 3 | 52 | | 3 | 2 | 37 | | 4 | 1 | 16 | | 5 | 1 | 21 | +---------+-------------+----------+ 5 rows in set (0.00 sec) mysql> select ClassID,Count(Name) from stars group by ClassID having Count(Name) >= 2; +---------+-------------+ | ClassID | Count(Name) | +---------+-------------+ | 2 | 3 | | 3 | 2 | +---------+-------------+ 2 rows in set (0.01 sec) mysql> select ClassID from stars group by ClassID having sum(Age) >=50; +---------+ | ClassID | +---------+ | 2 | +---------+ 1 row in set (0.00 sec) mysql>
8.只返回有用的行
关键字:LIMIT(一个数为显示的行数,两个数字为偏移第一个数字行,显示第二个数字)
案例展示:
mysql> select * from stars; +-----+----------+-----+--------+-------------+---------+ | SID | Name | Age | Gender | Tearch | ClassID | +-----+----------+-----+--------+-------------+---------+ | 1 | zhangsan | 27 | boy | sunwokong | 1 | | 2 | lisi | 26 | boy | zhubajie | 3 | | 3 | wanwu | 21 | boy | shaseng | 5 | | 4 | zhaoliu | 17 | boy | yudi | 2 | | 5 | qianqi | 16 | boy | wanmu | 4 | | 6 | yanba | 21 | boy | change | 2 | | 7 | chenshi | 11 | girl | erlangsheng | 3 | | 8 | liuer | 14 | boy | NULL | 2 | +-----+----------+-----+--------+-------------+---------+ 8 rows in set (0.00 sec) mysql> select * from stars limit 2; +-----+----------+-----+--------+-----------+---------+ | SID | Name | Age | Gender | Tearch | ClassID | +-----+----------+-----+--------+-----------+---------+ | 1 | zhangsan | 27 | boy | sunwokong | 1 | | 2 | lisi | 26 | boy | zhubajie | 3 | +-----+----------+-----+--------+-----------+---------+ 2 rows in set (0.00 sec) mysql> select * from stars limit 2,3; +-----+---------+-----+--------+---------+---------+ | SID | Name | Age | Gender | Tearch | ClassID | +-----+---------+-----+--------+---------+---------+ | 3 | wanwu | 21 | boy | shaseng | 5 | | 4 | zhaoliu | 17 | boy | yudi | 2 | | 5 | qianqi | 16 | boy | wanmu | 4 | +-----+---------+-----+--------+---------+---------+ 3 rows in set (0.00 sec) mysql>
9.select语句的执行流程
from clause --> where clause --> group by --> having clause -->order by --> select -->limit
select常用的修饰符:
distinct 重复的只显示一次
SQL_CACHE 缓存查询结果
SQL_NO_CACHE 不缓存查询结果