如果你没有数据练习,请看我这篇博客
现在开始练习(以下练习都是以上面的数据集作为练习数据)
1.JOIN
left join
返回左表拥有的emp_no,
select e. emp_no, birth_date, first_name, last_name, gender, salary from employees e left join salaries s on e. emp_no = s. emp_no
select e. emp_no, birth_date, first_name, last_name, gender, salary from employees e left join salaries s on e. emp_no = s. emp_no where s. emp_no is null
right join
返回右表拥有的emp_no
select e. emp_no, birth_date, first_name, last_name, gender, salary from employees e right join salaries s on e. emp_no = s. emp_no
select e. emp_no, birth_date, first_name, last_name, gender, salary from employees e right join salaries s on e. emp_no = s. emp_no where s. emp_no is null
inner join
返回左右表都有的emp_no
select e. emp_no, birth_date, first_name, last_name, gender, salary from employees e inner join salaries s on e. emp_no = s. emp_no
full join / full outer join (Oracle数据库支持full join,mysql是不支持full join的,但仍然可以同过左外连接+ union+右外连接实现)
返回左表所有有的emp_no和右表所有的emp_no
select e. emp_no, m. emp_no, first_name, last_name, motto from employees e full join motto m on e. emp_no = m. emp_no
2.UNION
select e. emp_no, birth_date, first_name, last_name, gender, salary from employees e left join salaries s on e. emp_no = s. emp_no where s. emp_no is null
union
select e. emp_no, birth_date, first_name, last_name, gender, salary from employees e right join salaries s on e. emp_no = s. emp_no
3.EXPLAIN
在日常工作中,我们会有时会开慢查询去记录一些执行时间比较久的SQL语句,找出这些SQL语句并不意味着完事了,些时我们常常用到explain这个命令来查看一个这些SQL语句的执行计划,查看该SQL语句有没有使用上了索引,有没有做全表扫描,这都可以通过explain命令来查看。所以我们深入了解MySQL的基于开销的优化器,还可以获得很多可能被优化器考虑到的访问策略的细节,以及当运行SQL语句时哪种策略预计会被优化器采用。
执行EXPLAIN可以查询 到以下字段
字段名 意义 id 表示查询中执行select子句或操作表的顺序序列号( id如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行) select_type 查询类型 table 显示 这行数据关于哪一张表 type 访问类型 possible_keys 显示可能应用在这张表中索引,一个或多个,,但不一定被查询实际用到 key 实际用到的索引 key_len 表示索引中使用的字节数,查询中使用的索引长度,越短越好 ref 哪些列字段或常量被用于查找索引列上的值 rows 找出数据所需要读取的行数 extra(#extra) 额外的信息描述
- id
explain select t2. * from t1, t2, t3 where t1. id = t2. id and t1. id = t3. id and t1. col_1 = ''
explain select t2. * from t2 where id = ( select t1. id from t1 where id = ( select t3. id from t3 where t3. col_1 = '' ) )
- select_type
查询类型只要区别,普通查询,联合查询,子查询的复杂查询
名字 介绍 SIMPLE 简单的select查询,查询中不包含子查询或者UNION PRIMARY 查询中若包含任何复杂 的子部分,最外层查询则标记为PRIMARY SUBQUERY 在SELECT或WHERE列表中包含子查询 DERIVED 在FROM列表中包含子查询,MYSQL会递归执行这些子查询把结果放在临时表 UNION 若在第二个SELECT出现UNION就标记为 UNION,若UNION包含在FROM子句的子查询中,外层SELECT将被标记为DERIVED
- type
全
部
访
问
类
型
\color{#FF0000}{全部访问类型}
全 部 访 问 类 型
system > const > eq_ref > ref > fulltext > ref_or_null > index-merge > unique_subquery > index_subquery > range > index > ALL
常
用
访
问
类
型
\color{#FF0000}{常用访问类型}
常 用 访 问 类 型
system > const > eq_ref > ref > range > index > ALL
一
般
来
说
至
少
要
达
到
r
a
n
g
e
级
别
为
好
,
最
好
到
达
r
e
f
级
别
\color{#FF0000}{一般来说至少要达到range级别为好,最好到达ref级别}
一 般 来 说 至 少 要 达 到 r a n g e 级 别 为 好 , 最 好 到 达 r e f 级 别
级别 描述 system 表只有一行数据(等于系统表),平时不会出现,可以忽略不计 const 表示通过一次索引就找到了,const常用于比较primary和unique索引,因为只匹配一行数据 eq_ref 常用于比较primary和unique索引,对于每个索引键,表中都只有 一条记录与之匹配 ref 用于非primary和unique索引,返回匹配某个单独的所有行 range 给定范围的索引查询,一般出现 关键字 between,>,< index 读取全表,因为index只读取索引树,通常比all快,因为索引文件比数据文件小 all 读取全表,从硬盘中读取数据文件
const和eq_ref的区别 (刚开始我也分不清,后面知道了,分享一下)
两者相同都是用于比较primary和unique索引,不同地方是,const是通过一次索引比较,找出一条记录,而eq_ref是对于每个索引键,表中都只有 一条记录与之匹配,找出1条记录,看以下sql,品一下
const
explain select * from t1 where id = 1
eq_ref
explain select * from t1,t2 where t1.id = t2.id
- extra
名称 描述 SQL性能 Using filesort MYSQL无法利用索引完成的排序称作为“文件排序” 差 Using temporary 使用了临时表保存中间结果,MYSQL在对查询结果排序时使用了临时表 极差 Using index 表示索引被作为读取字段进行查找 优 Using where 表示索引被作为条件进行查找 优 Using join buffer 使用了join连接查询缓冲区 一般 impossible where 不可能的条件 无 select tables optimized away MySQL根本没有遍历表或索引就返回数据了 优 distinct 优化distinct操作,在找到第一个匹配的数据后停止查找 优
以上就是EXPLAIN关键字的介绍,想进行优化SQL练习的请看我这篇博客
4.EXISTS / NOT EXISTS
EXISTS(包括 NOT EXISTS )子句的返回值是一个BOOL值。 EXISTS内部有一个子查询语句(SELECT … FROM…), 我将其称为EXIST的内查询语句。其内查询语句返回一个结果集。 EXISTS子句根据其内查询语句的结果集空或者非空,返回一个布尔值。将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,这一行行可作为外查询的结果行,否则不能作为结果,反而反之
例子
select * from salaries s where emp_no in ( select emp_no from employees )
select * from salaries where exists ( select emp_no from employees )
可以看到查询结果都一样,但是执行时间不一样,一个用in嵌套子查询,一个用exists内查询,因为salaries是数据比employees的数据要多,所以in查询相当于大表驱动小表,相当于他要去salaries表循环N次,每次要去employees表查找是否有相同emp_n,而exists是小表驱动大表,遍历employees表中数据,如果满足salaries表中emp_no数据相同则返回emp_no作为外查询作为结果集。小表驱动大表是推荐,效率高
5.VARIABLES
mysqld服务器维护两种变量。——GLOBAL变量 / SESSION变量
当mysql启动他就会按照 my.ini 里的配置信息 设置到 GLOBAL变量中, 当有一个客户端来连接,就会将GLOBAL的配置信息变量 复制到 新创建的这个SESSION变量中维护。所以当MYSQL重启就会重新把my.ini中配置信息放入GLOBAL中。
1.想要永久该配置信息就要改 my.ini文件
2.想要临时改变配置信息,选择可以改变GLOBAL或SESSION
SET GLOBAL var_name = var_val
SET SESSION var_name = var_val
SET var_name = var_val
GLOBAL 和 SESSION 的区别就是,改变GLOBAL变量,后续连接的客户端也会改变,但不影响已连接的客户端,如果SESSION变量改变了,只影响执行该SQL的当前客户端,不影响其他 ,当客户端断开连接,重新连接他又是从GLOBAL中初始化配置信息
6.PROFILES / PROFILE
用于分析当前连接客户端会话中语句执行的资源消耗情况,可用于SQL调优测
默认参数处于关闭状态,开启后 保存最近15次的运行结果
SHOW VARIABLES like 'profiling'
SET profiling= on
SHOW PROFILES
SHOW PROFILE FOR QUERY 查询ID
SHOW PROFILE 还可以显示其他详细的性能消耗信息
名称 作用 ALL 显示所有的开销信息 BLOCK IO 显示块IO相关开销 CONTEXT SWITCHES 上下文切换相关开销 CPU 显示CPU相关开销信息 IPC 显示发送和接收相关开销信息 MEMORY 显示内存相关的开销信息 PAEG FAULTS 显示页面错误相关开心信息 SOURCE 显示和Source_function,Source_file,Source_line相关的开销信息 SWAPS 显示交换次数想相关开销的信息
SHOW PROFILE CPU, SOURCE FOR QUERY 查询ID
当你的SQL性能消耗信息STATUS中出现了以下,你要注意
SATATUS 描述 危险等级 converting HEAP to MyISAM 查询结果太大,内存都不够使用,搬去磁盘了 危险 Creating tmp table 拷贝查询结果到临时表,用完再删除 危险 Copying to tmp table on disk 把内存中临时表复制到磁盘 极危险
因为 SHOW PROFILES 是显示15条,不能显示全部,如果要查询全局就要开启 全局日志查询(他会记录所有查询SQL)
此功能最好在测试环境中开启,因为生产环境中会占用性能,使性能下降
SET general_log = 1
SHOW VARIABLES LIKE 'general_log_file'
SHOW VARIABLES LIKE 'log_output'
SET GLOBAL log_output = 'TABLE'
7.FUNCTION
mysql的自定义函数,用于封装自定义方法
7.1. 创建函数
DELIMITER $$
DROP FUNCTION IF EXISTS 方法名$$
CREATE FUNCTION 方法名( 形参变量名 形参数据类型) RETURN 返回参数类型
BEGIN
. . . . . ;
. . . . . ;
RETURN 返回参数;
END $$
8.PROCEDURE
存储过程,用于批量执行sql语句逻辑,与 函数 区别是没有返回值
8.1. 创建存储过程
DELIMITER $$
DROP FUNCTION IF EXISTS 存储过程名$$
CREATE FUNCTION 存储过程名( 形参变量名 形参数据类型)
BEGIN
. . . . . ;
. . . . . ;
END $$
8.2. 调用存储过程
DELIMITER $
CALL 存储过程名( 参数变量. . ) $
9.更多关键字正在持续的更新中。。。
一键查询淘宝/拼多多内部优惠券,每日大额外卖红包,购物省钱的宝藏工具