这条语句是符合一星的,因为索引是按照 age 从小到大排序的,所以 age = 20 的数据肯定是在一起的
二星
select * from user where age = 20 order by name;
这条语句符合一星,但不符合二星,因为数据列的顺序是按照 age 排序的,如果现在改成 name 排序,可能导致索引顺序与 order by 排序结果不同,结果如下:
文章插图
文章插图
select * from user where age = 20 order by age
这条查询语句则符合一星和二星三星
select * from user where age = 20
这条语句不符合三星,因为索引列中只有 id 和 age,没有 nameselect age from user where age = 20
这条语句则符合三星,因为只查询了 age,age 在索引中存在,不需要回表4.2 回表上面三星索引提到了一个次回表,那么回表是什么?
简单点说,就是查询语句中需要的列,在索引中不包含,需要根据主键 id 再查询一次才能获取到 。回表相当于多查询一次,再查询时我们要尽量避免回表查询 。
因为普通索引中只包含了对应列和主键的值,比如 age 索引,那么 age 索引中包含的数据有 age,id 。此时如果需要 name 的话,需要先通过 age 索引找到对应的 id,然后再去主键索引上找到 name,主键索引包含了一行所有记录的值 。这里回答了上面的问题,为什么 MySQL 一定要有主键索引,因为主键索引子节点中包含了全部数据
文章插图
4.3 索引覆盖
CREATE TABLE `user` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(10) NOT NULL,`age` int(1) DEFAULT NULL,`sex` varchar(2) DEFAULT NULL,PRIMARY KEY (`id`),KEY `idx_name_age` (`name`,`age`)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;select name,age from user where name = "张三"-- 这条语句就使用了索引覆盖,因为 name 和 age 再 idx_name_age 索引中都有,不需要回表查询select name,age,sex from user where name = "张三"-- 如果加上了 sex,那么就需要回表查询了,因为索引中不存在 sex 字段
5 索引优化5.1 慢查询5.1.1 简介慢查询日志是MySQL 提供的日志记录,用来记录所有的慢 SQL 语句,我们可以通过设置慢查询的时间阈值 long_query_time,来定义什么样的 SQL 是慢 SQL 。通过慢查询日志我们可以找出需要优化的 SQL,下一步就是进行 SQL 优化5.1.2 慢查询配置第一步:我们可以通过 show variables like 'slow_query_log' 语句查询慢查询是否开启,默认是关闭(OFF)
文章插图
slow_query_log_file 是慢查询日志存放的位置,如果是 window 的话,通常在你的安装文件夹 Data 目录下
第二步:打开慢查询
set global slow_query_log= 1;
第三步:设置慢查询阈值什么样的查询叫做慢查询呢?1s,5s 还是 10s,这点 MySQL 不知道,所以需要我们通过配置去设置 long_query_time 参数
文章插图
通过命令 show variables like '%long_query_time%' 查看慢查询时间,默认是 10 s
如果需要修改,可以通过命令
set global long_query_time = 5
来设置文章插图
注意:这里通过
set global long_query_time = 5
设置完慢查询时间后,再次查询发现慢查询时间依然是 10s,难道是设置没生效?使用此命令修改后,需要重新连接或者新开启一个会话就可以看到修改后的配置
经验总结扩展阅读
- 如何优雅的备份MySQL数据?看这篇文章就够了
- 【博学谷学习记录】超强总结,用心分享|MySql连接查询超详细总结
- 一文讲清楚 JVM Safe Point
- day08-MySQL事务
- MySQL 窗口函数
- 线上服务宕机,码农试用期被毕业,原因竟是给MySQL加个字段
- mac通过docker一键部署MySQL8
- day07-2MySQL索引
- CentOS部署MySQL
- MySQL用户也可以是个角色