MySql基础

Mysql相关

(关系型数据库:表和表之间存在连接关系)

1. 什么是表

表是数据库的基本组成单元,所有的数据都以表格的形式组织,目的是可读性强。

2.sql语句的分类

增删改查有一个术语:CRUD操作
create (增) retrieve(检索) Update (修改) Delete(删除)
DQL(Data Query Language):(数据查询语言)查询语句,select 语句
DML(Data Manager Language):(数据操作语言)insert , delete ,update 对表中数据进行增删改语句
DDL (Data Definition Language) :(数据定义语言)creat , drop,alert分别是对表结构的增删改。
TCL (Transaction Control Language):(事物控制语言)commit提交事物,rollback回滚事物
DCL(Data Control Language):(数据控制语言)grant 授权,revoke撤销授权。

3.常用的MySQL命令

登录 mysql -u用户名 -p密码
quit/exit //退出mysql
查看使用
执行sql语句 source sql 文件所在的目录
查看表结构 desc
create database 库名;创建一个库
show database;查看有哪些库
use 库名;进入这个库
show tables;查看表
truncate table 表名
select version()查看数据库的版本
\c 结束一条sql语句
查看创建表的sql语句

4.sql语句

sql语句执行顺序
select          5
字段名
from            1
表名
where           2
条件
group by        3
字段名
having          4
..
order by        6
.. 
limit           7
...

1.在查询的字段上面是可以进行数学运算的

例如 test表中有字段数月薪(mouthSalary),需要查询年薪
sql:   select  mouthSalary*12 from test

2.between … and …

在100到230之间的数据
between  100  and 230
同样也可以使用在字符串方面 但是不常用

3.查询字段的值为空的数据

WHERE s_score IS NULL; 可以直接在要判断的字段后面添加 is null
也可以使用ISNULL(字段名);也可以使用ISNULL函数进行判断
注意:不可以使用    字段名=null 进行判断

4.in和not in 的使用方法

in等同于or
比如 :WHERE s_score  IN (80,90)是等同于 WHERE s_score = 80 OR  s_score =90 的
注意in 后面的条件不是一个区间而是一个数组,就是要查询的字段的值是等于这个数组中的某个值
not in就是不等于数组中的值

5.模糊查询

like的用法(需要掌握两个特殊符号%和_)
% 表示多个字符 ,   _表示一个字符
找出名字中有O的 where name like  '%o%';
找出名字第二个字母是A的 where name like  '_A%';

6.转义字符

\

7.排序

order by
例子:按照分数的降序排列,当分数相同的时候按照名字的升序排列
select *  from  score order by s_score desc , s_name asc;

8.单行处理函数

输入一行,输出也是一行
注意:当行处理函数在数据库中只要是null值参见运算,结果一定是null

9.ifnull函数(单行处理函数)

空处理函数
ifnull(a,b)
需要传两个参数
a:可能为空的字段
b:如果字段的值是null,给此字段赋的值
例如:ifnull(score,0) 含义就是如果表中有一行数据,其中score字段的值是null,
则给score字段赋值为0。

10.分组函数(多行处理函数)

count 计数
(在不使用group by 的情况下count(*) 是统计表中总记录条数。
 count(字段名)是统计某个字段不为null的数据的总数)
 
sum 求和
avg 求平均值
max 最大值
min 最小值
分组函数都是对某一组函数进行操作的。
分组函数自动忽略null;

11.group by 和having

group by:按照某个字段或者某些字段进行分组
having:对分组之后的数据再次进行过滤

例子
找出每门课程的平均值
(SELECT c_id, AVG(s_score) avgScoreNum FROM score GROUP BY c_id)
注意 :分组函数一般都和group by 一起使用,并且任何一个分组函数都会在group by 语句
执行完毕之后执行的,而group by 语句是在where语句执行完毕之后执行的。

当一条sql语句没有group by的话,整张表会自成一组数据。

当一条sql语句中有group by的话,那么select后面只能跟关于该字段的分组函数和字段。

例如:SELECT s_id, c_id, AVG(s_score) avgScoreNum FROM score 
GROUP BY c_id  这条sql语句在mysql中是可以执行的,但是结果是错误的。
在Oracle中会报错的。

group by后面是可以跟多个字段的
例如有一张员工表(employee),表中有字段id,员工姓名,员工所属部门,员工的岗位,
员工的薪资。一个公司有多个部门,一个部门有多个岗位,每个岗位有多个员工。

需要查询出每个部门,不同岗位的平均工资
select 部门, 岗位, avg(工资) from employee group by 部门,岗位;

同样是上面员工表的例子
要求查询每个部门中的最高工资且最高工资大于2000的数据
有两种解决方案
1.先查询出每个部门的最高工资,再使用having筛选出最高工资大于2000的。
 select  部门, max(工资) from employee  group by  部门 
 having max(工资) > 2000;
2. 因为要查询出的最高工资是表中原有的数据,所以可以先使用where条件筛选出
大于2000的工资,然后再对其进行分组。
select  部门, max(工资) from employee where 工资>2000  group by  部门 
结论:建议使用2方法实现要查询的数据,因为having的执行效率比较低。

having什么时候使用呢??
当我们的查询条件依赖分组函数查询出的数据的时候使用。
比如 查询出每个部门的平均工资,并且平均工资的值大于2000
这个时候我们要查询出的数据是需要跟平均工资相比较的,所以要先查询出平均工资,然后使用
在having后面添加过滤条件。
select 部门, avg(工资) from employee group by 部门 having avg(工资) >2000;

12.distinct用法

distinct只能出现在查询所有字段的最前面,而且是对所有的字段进行去重。

案例:统计岗位的数量
select count( distinct 岗位) from  employee

13.连接查询

根据表的连接方式分为
内连接:
	等值连接
	非等值连接
	自连接
外连接
	左连接
	右连接
全连接
在表的连接查询方面有一种现象:笛卡尔乘积现象

14.内连接之等值连接

老师表,课程表,学生表,分数表

四张表分别是老师表,课程表,学生表,分数表

案例 :查询出每个学生姓名和平均成绩
SELECT s1.s_name, AVG(s2.s_score) 
FROM student s1
INNER  JOIN
score s2
ON
s1.s_id = s2.s_id
GROUP BY
s1.s_name
以上sql语句使用的是内连接,且ON后面跟的连接关系是一个等值关系,
这就是内连接的等值连接。

15.内连接之非等值连接

内连接的条件不是使用的等值关系
例如 有一张员工表 employee ,其中有员工姓名 name,员工工资 sal,等字段
	有一张表是薪资等级表salgrade,有薪资等级grade,有最低工资(minsal),
	最高工资(maxsal)等字段
	
	要查询每个员工的工资等级
	select e.name , s.grade
	from 
	employee  e
	inner join
	salgrade s
	on 
	e.sal between s.minsal and s.maxsal

16.内连接之自连接

员工表

例如有员工表,其中id是员工编号,ename是员工姓名,pid是员工领导
要查询出每个员工的领导,要显示员工姓名和领导姓名
SELECT
 e1.ename 员工, 
e2.ename 领导
FROM
empl e1
LEFT JOIN
empl e2
ON
e1.pid= e2.id
解决思路就是要把一张表看成e1(员工)表和e2(领导)两张表,
当员工的pid等于领导的id之后,
我们需要的就是员工的姓名(e1.ename)和领导的姓名(e2.ename)

17.外连接

最主要的特点是主表的数据无条件的全部查询。
假设A和B两张表使用外连接,则A,B两张表是有一张表为主表,一张为副表,则主要查询的是
主表的数据,然后查询副表匹配连接条件的数据,当没有匹配上时,副表会自动模拟出null值
与之匹配。

18.内连接和外连接的区别

学生表,成绩表

内连接是将两张表中根据连接条件能够匹配的上的数据查询出来,
例如在以上两张表中,使用内连接查询学生的s_id、姓名、课程号、学生成绩。
SELECT
s1.s_id,
s1.s_name,
s2.c_id,
s2.s_score
FROM
student s1
INNER     JOIN
score s2
ON
s1.s_id = s2.s_id
sql语句如上,两张表的连接条件是s_id相等,对比两张表的数据,可以发现两张表根据s_id
关联后,数据能够匹配的上s_id是01到08,此时查询结果是两张表等于这些id的数据。
查询结果就是如下图

在这里插入图片描述

外连接,学生表和成绩表进行连接,以其中一张表为主表,一张表为副表,以主表的数据为
主,副表中没有主表的数据,则以空值填补
例如,以学生表为主,同样查询学生的s_id、姓名、课程号、学生成绩。
SELECT
s1.s_id,
s1.s_name,
s2.c_id,
s2.s_score
FROM
student s1
LEFT      JOIN
score s2
ON
s1.s_id = s2.s_id
sql语句如上,其中使用的是左连接,而左边的表是学生表,关联条件是s_id=s_id,
所以查询出学生表所有的s_id,然后再到成绩表中找出和学生表中s_id相等的数据,
其中成绩表中符合连接条件的数据是20条,但是在主表学生表中还有两条数据不符
合连接条件,也就是,在成绩表中没有这两条数据,所以成绩表中自动模拟出null值
与之匹配。

在这里插入图片描述

同样,右连接也是和以上左连接的原理是一样的。
SELECT
s1.s_id,
s1.s_name,
s2.c_id,
s2.s_score
FROM
student s1
RIGHT JOIN
score s2
ON
s1.s_id = s2.s_id

在这里插入图片描述

19.全连接(了解一下,一般不用)

  1.通过union连接的SQL它们分别单独取出的列数必须相同;

  2.不要求合并的表列名称相同时,以第一个sql 表列名为准;

  3.使用union 时,完全相等的行,将会被合并,由于合并比较耗时,
     一般不直接使用 union 进行合并,而是通常采用union all 进行合并;

  4.被union 连接的sql 子句,单个子句中不用写order by ,因为不会有排序的效果。
     但可以对最终的结果集进行排序;

       (select id,name from A order by id) 
       union all (select id,name from B order by id); //没有排序效果

       (select id,name from A ) union all 
       (select id,name from B ) order by id; //有排序效果

union
union all

20 .limit

在sql语句中是最后执行的
用法 limit startIndex , length
其中 
startIndex 表示的是要查询的第一条数据的下标,一个表格中第一条数据的下标是0
length 表示的是从startIndex后面取几个数据
例如 查询班级中成绩排名前五的学生 其中表中有字段是学生姓名,学生成绩,学生id。

select stu_name from score order by stu_score limit 0,5;

其中标准的分页,前端要传的参数是第几页(pageNum),每页显示多少条(pageSize)
sql语句中的startIndex ,length跟pageNum,pageSize的关系如下
length= pageSize;startIndex =(pageNum-1)*  pageSize

21.表的复制

语法:create table 表名 as DQL语句
将查询结果当做表创建出来

22.表的插入

普通的Sql语句
insert into 表名 (字段1,字段2,字段3) values (值1,值2,值三);
或者是全部字段都插入数据时 例如在表中只有三个字段。
insert into 表名 values (值1,值2,值三);

将查询结果插入到一张表中
语法:insert into 表名 DQL语句
但是上面的语句的前提是要插入数据的表的字段要和DQL查询语句查询出的字段一致

23. 更新表数据语句

update 表名 set 字段1 = 值1 ,字段2 = 值2 ....  
where 条件; 
不加where条件的话默认是更新整张表的数据。

24. 删除语句

delete from 表名 where 条件
不添加条件默认删除所有的数据。

25.怎么删除含有大量数据的表(大表)

truncate table 表名 (用于大表,但是一定要谨慎使用,一旦删除不可恢复)

26.表的结构修改

增加列: alter table 表名 add 列名 类型(长度) 约束;
修改现有列类型、长度和约束 语法:alter table 表名 modify 列名 
类型(长度) 约束;
修改现有列名称 语法:alter table 表名 change 旧列名 新列名 
类型(长度) 约束;
删除现有列 语法:alter table 表名 drop 列名 ;
修改表名 rename table 旧表名 to 新表名;
修改表的字符集:alter table person character set utf8;

27. 主键

主键的作用: 主键值是当前行的数据的唯一标识。
主键的分类:
	根据主键字段的数量进行划分
		单一主键(以其中一个字段为主键)
		复合主键(将表中多个字段联合起来添加一个主键约束,不推荐使用,
		违背数据库设计的三范式)
	根据主键的性质进行划分
		自然主键:和业务没有任何关系。
		业务主键:主键和系统的业务挂钩,例如,拿着身份证号作为主键。
一张表只能有一个主键约束

28.外键约束

外键约束:foreign key
外键字段:有外键约束的字段
外键值:外键字段的值
加上外键约束的字段必须要和数对应表的字段的值一样
例如
student表中class_id引用class表中的id,那么学生表中class_id中的值
必须是在班级表中id含有的值。
其中学生表是子表,班级表是父表,在进行数据的添加时,应该现在父表中添加
数据,然后在子表中添加数据,在进行数据的删除时,应该先删除子表的数据,
然后删除父表的数据。


外键值是可以为空的。
外键可以引用非主键的字段,但是字段值要保证唯一性。

29.存储引擎

什么是存储引擎?
表的存储方式。在Oracle中就叫做表的储存方式。
常见的存储引擎
InnoDB (mysql默认使用的存储引擎)
	支持事务,行级锁,外键等,可以保证数据的安全性
	表的结构存储在xxx.frm文件中
	数据存储在的表tablespace这样的表空间中(是一种逻辑概念),无法被压缩,
	无法转换为只读。
	在MySQL数据库崩溃之后提供自动恢复机制
	支持级联删除和级联更新。
	
MYISAM 
	不支持事务
	特征
		管理表有三个文件
			1.格式文件   存储表的结构;(mytable.frm)
			2.数据文件   存储表中每一行的数据; (mytable.MYD)
			3.索引文件   存储表中的索引;(mytable.MYI)
		灵活的AUTO_INCREAMENT字段处理
		可被压缩节省空间,并且可以装换为只读表,用来提高检索效率。
		
		
MEMORY
	优点:查询速度最快
	缺点:不支持事务,因为所有的数据和索引都存储在内存中,数据容易丢失。

30.事务

一个事务是一个完整的逻辑单元 ,不可以再分。
比如 银行用户转账,A账号给B账号转账1000元,A账户里的余额需要减少一千元,
B账户余额需要增加一千元,这是两条更新语句,这两条更新语句只能有两种结果,
要么同时成功,要么同时失败。那么在这个过程中需要用到数据库的“事务机制”

和事务相关的语句只有DML语句。

31.事务的特性

事务包括四大特性
原子性:事务是工作的最小单元,一个事务不能再分割
一致性:事务必须保证多条DML语句同时成功,或者同时失败
隔离性:事务和事务之间不能相互干扰。
永久性:最终的数据必须持久化到硬盘文件中。

32.事务的隔离性

第一级别:读未提交
	事务读取的是另一个事务未提交的数据,,容易产生脏读
第二级别:读已提交 
	事务读取的是另一个事务已经提交的数据,解决了脏读,但是会产生不可重复读
第三级别:可重复读  (MySQL数据库默认的隔离级别)
	不会产生脏读、不可重复读,但是会产生幻读。
第四级别:序列化读/串行化读
	将事务进行了排队,一个事务没有结束,另一个事务不能开始
	解决了脏读,不可重复读,幻读。
	但是这样执行效率会变低。

33.脏读 不可重复读 幻读

  1. 脏读:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
    例如:
    张三的工资为5000,事务A中把他的工资改为8000,但事务A尚未提交。
    与此同时,
    事务B正在读取张三的工资,读取到张三的工资为8000。
    随后,
    事务A发生异常,而回滚了事务。张三的工资又回滚为5000。
    最后,
    事务B读取到的张三工资为8000的数据即为脏数据,事务B做了一次脏读。
  2. 不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
    例如:
    在事务A中,读取到张三的工资为5000,操作没有完成,事务还没提交。
    与此同时,
    事务B把张三的工资改为8000,并提交了事务。
    随后,
    在事务A中,再次读取张三的工资,此时工资变为8000。在一个事务中前后两次读取的结果并不致,导致了不可重复读。
  3. 幻读:
    具体看以下实例
    (1) 事务A
# 设置事务的隔离级别是可重复读,并开启事务A;
mysql> set session transaction isolation level repeatable  read;
mysql>start transaction;
mysql> select * from jmeter_contacts where id = 1;
Empty set (0.00 sec)

以上结果可以发现在A事务中没有查询到A等于1的数据;现在打开另一个窗口,开启事务B
(2)事务B

# 设置事务的隔离级别是可重复读,并开启事务A;
mysql> set session transaction isolation level repeatable  read;
Query OK, 0 rows affected (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
#向表中插入id为1的数据,并提交事务
mysql>  insert into jmeter_contacts (id,  user_id ,dingding_token,is_deleted) values  (1, 123,  'adadas', 0 );
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

(3) 接下来事务A再次查询id为1的数据

mysql> select * from jmeter_contacts where id = 1;
Empty set (0.00 sec)

# 因为是可重复读,所以还是没有查询到数据;
# 那接下来让我们同样在数据库中插入id为1的数据,
mysql> insert into jmeter_contacts (id,  user_id ,dingding_token,is_deleted) values  (1, 123,  'adadas', 0 );
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
# 这时,问题就暴露出来了,明明我在本事务中没有
# 查询到id为1的数据,为啥还是不能插入id为1的数据呢?
# 难道是我的查询产生幻觉了?

34.索引

主键和具有unique(不能重复)的字段会自动添加索引,不需要手动添加
查看sql语句的执行计划 explain SQL语句
当查询数据时,条件上面的字段没有添加索引的话是进行全表扫描的。

什么是索引

索引就相当于一本书的目录,通过索引可以快速查找所需要的内容

在数据库中查找数据的方式可以分为两种

一是直接全表进行检索
二是通过索引进行检索 

索引的优缺点

优点:索引可以在数据量很多的时候极大的提高检索效率。
缺点:索引不能随意的创建,因为索引也是需要创建成本的,索引是需要经常进行去维护的。
一旦添加索引的字段进行修改,索引就需要重新排序。

什么时候考虑添加索引

数据量很大的时候,
添加索引的字段不经常进行修改
该字段经常出现在where语句中

怎么创建索引

create index 索引名 on 表名(字段名)

怎么删除索引

drop index 索引名 on 表名;

mysql索引底层数据结构

采用的是B+Tree	
B+Tree所有叶子结点才有指向数据的指针。非叶子结点就是纯索引数据和主键。
每个叶子结点都有指向下一个叶子结点的链接。

索引的实现原理

执行创建索引语句后,会对全表的数据进行排序之后,创建一个有顺序的索引,
索引之后会进行分区,就跟字典的目录一样分为A区,B区,.... Z区,然后将分
区后的数据拆分到B+Tree上面。

根据添加索引的字段进行查询的时候,先查看对应的字段有没有索引对象,
有的话,通过索引进行在索引对象中检索,比如根据sname= 'SMITH',首先会先定位到S区,
然后根据定位到M区...,定位到SMITH,SMITH这个位置会存储着表中当前行数据在硬盘中
的物理地址,所以可以直接拿到这个物理地址去查询当前行的数据。

索引的分类

大类:聚簇索引和非聚簇索引。

单一索引:给单个字段添加索引
复合索引:给多个字段添加一个共同的索引
主键索引:主键上面的索引,自动添加
唯一索引:有unique约束的字段上面的索引,自动添加。

主键索引和唯一索引的区别

 主键是一种约束,唯一索引是一种索引,两者在本质上是不同的。
 主键创建之后一定会包含一个唯一索引,但是唯一索引不一定是主键索引
 唯一索引是在字段为unique的时候创建的.
 唯一索引的列允许空值,而主键索引列不允许为空值
 主键可以被其他表作为外键,而唯一索引的列不能
 一个表最多只能有一个主键, 唯一所以可以有多个

聚簇索引和非聚簇索引

聚簇索引
(1)只能来自于采用Innodb存储引擎的数据
(2)自动采用主键创建索引,这个索引就是聚簇索引
(3)没有主键的话,会自动采用具有唯一标识的字段为聚簇索引
(4)如果既没有主键,又没有具有唯一标识的字段,会随机选一个字段创建聚簇索引
(5)在innodb引擎的表中,一定会有一个聚簇索引,并且只能有一个
(7)在除了聚簇索引字段上面创建的索引都是非聚簇索引

非聚簇索引
(1)由开发人员创建的
(2)对于innodb引擎的表中,在除了聚簇索引字段上面创建的索引都是非聚簇索引
(3)在采用MyIsam引擎的表中,所有索引都是非聚簇索引。

索引什么时候失效

使用like '%A%'
因为第一个是%的话不能根据首字符查询字段的所在分区。

35.视图

什么是视图

站在不同的角度去看待数据(同一张表的数据,通过不同的角度去看)

怎么创建和删除视图

创建视图:create view myview as select id,sname from student
删除视图:drop view myview
只有DQL语句才能通过以视图对象的方式创建出来。

视图的作用

隐藏表的细节,可以隐藏表中一些机密性比较高的字段保密级别比较高的系统,
一般保密性比较高的系统只对外提供相关的视图,我们通过视图间接的对数据
库原表中的数据进行操作。

36.数据库的导入导出

数据库的导出

在windows的dos窗口执行
mysqldump 数据库名称 > 文件路径/文件名称.sql -uroot -p
导出数据库的表
mysqldump 数据库名称   表名称> 文件路径/文件名称.sql -uroot -p

数据库的导入

create database 数据库名称
use 数据库名称
source 文件路径/文件名称.sql

37. 数据库表设计的三范式

目的:减少表中数据的冗余

第一范式:一张表中至少有一个主键,且每个字段都是不可以再分割的。

第二范式:在第一范式的基础上,一张表中非主键字段完全直接主键字段,不能依赖部分主键
	比如一张表中有一个复合主键,复合主键对应的字段是学生id和老师id,而表中有字段学生
	姓名和老师姓名,其中学生姓名只是依赖学生id,不依赖老师id,同样老师也是。这种情况
	就是部分依赖主键。	
第三范式:在第二范式的基础上,所有非主键字段只能依赖主键,不能产生传递依赖,非主键
和非主键之间不能有依赖关系。

38. 数据库表的经典设计方案

一对一
	1. 主键就是外键
	2. 外键唯一 (其中一个字段是外键,而且这个字段添加unique约束)
一对多
	两张表,多的表
	加外键
多对多
	三张表,在两张表之间添加关系表,关系表中有主键和跟两个表有关的外键

39. 查询语句中七个查询命令特征

  1. from

    作用
    1 将硬盘中的数据加载到内存中,生成一个全新的临时表;
    2 定位硬盘中已经存在的临时表;
    注意:
    1 在一个查询语句中第一个执行的永远是from;
    2 from定位的是一个临时表,这时临时表必须手动指定表名

  2. where

     作用:
     (1)操作from形成的临时表
     (2)循环遍历这个临时表中的每一行数据,将满足条件的数据行保存到
     	一个全新的临时表中
     注意:
     	由于where命令每次操作的是一行数据,因此在使用where命令时,
     不能使用聚合函数
    
  3. group by

    作用:
    (1)对临时表中的数据进行一次排序处理。
    (2)将具有相同特征的数据保存到同一个临时表中,例如按照男女分组,
    就会将所有的男生放到一个临时表中,把所有女生放到一个临时表中。
    注意:
    (1)使用多字段分组
    分组字段的执行顺序对于结果来说是没有任何影响的,从第二个分组字段开始操作的临时表都是由上一个分组生成的。
    (2)如果select操作的临时表是由group by 提供的,此时select将遍历group by
    生成的每一个临时表,在生成具体的临时表时,select只会从每一个临时表中读取对应字段的第一行数据。

  4. having

     作用		
     	对group by生成的临时表中不满足条件的数据删除
     注意
     	(1) having 不能单独出现,只能出现在group by后面
     	(2)having每次操作时的对象是一个临时表,因此判断条件应该来自于
     	聚合函数。
    
  5. select

     作用
     (1)当select操作的临时表是由from或者where命令提供时
     select会将指定字段的全部数据读取出来
     (2)当select操作的临时表是由group by命令提供时,
     select只会从每一个临时表中读取对应字段的第一行数据。
    
  6. order by

     作用:
     	只对select命令生成的临时表中的数据进行排序,将排序好的内容
     生成一个新的临时表。
     注意
     	如果使用字段名进行排序时,该字段可以不出现在select生成的临时表中
     	如果使用字段在表中的位置进行排序时(不常用),指定的字段必须在
     	select生成的临时表中
     出现。
    
  7. limit

     作用:对临时表中的数据进行截取。
    

40. 查询语句的特征

  1. 七个查询语句中,除了having命令,其他命令执行完毕之后都会形成临时表
  2. 七个查询语句中,除了from命令外,其他命令操作的临时表都是上一个命令生成的。
  3. 在当前查询命令执行完毕后,mysql会将上一个查询命令生成的临时表销毁掉,所以到最后只能看到一张临时表
  4. 在进行多字段分组时,从第二个分组字段开始,操作的临时表是上一个根据上一个分组字段生成的临时表

41. 造成查询语句执行效率慢的命令

  1. group by
    因为group by 要先将数据进行排序,而且分组过后可能会生成多个不同的临时表
  2. order by
    需要对select生成的临时表进行一次排序,然后再生成一个临时表
  3. where
    没有索引的话需要对临时表中的数据行进行遍历,数据量大的话,执行效率就会很慢
  4. limit
    如果指定的起始行数数值过大,导致查询效率变低
  5. 多表查询不指定表文件的执行顺序,会导致查询速度过慢
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值