[B站尚硅谷](https://space.bilibili.com/302417610/?spm_id_from=333.999.0.0)
## 1. 什么是索引
官方: 本质是一种数据结构, 是帮助MySQL高效获取数据的数据结构
是排好序的快速查找数据结构
## 2. 索引的优劣
### 1. 优势
* 提高数据检索效率,降低数据库的IO成本
* 降低数据排序成本,降低了CPU的消耗
### 2. 劣势
* 实际上索引也是一张表,该表保存了主键和索引字段,并指向实体表的记录,所以索引列也是要占用空间的
* 因为更新表时,MySQL不仅要不存数据,还要保存一下索引文件每次更新添加了索引列的字段,都会调整因为更新所带来的键值变化后的索引信息
* 索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立优秀的索引,或优化查询语句
## 3. 索引分类
* 单值索引 即一个索引只包含单个列,一个表可以有多个单列索引
* 唯一索引 索引列的值必须唯一,但允许有空值
* 复合索引 即一个索引包含多个列
## 4. 索引创建的基本语法
### 创建
如果是CHAR,VARCHAR类型,length可以小于字段实际长度;
如果是BLOB和TEXT类型,必须指定length。
```
CREATE [UNIQUE] INDEX indexName ON mytable(columnname(length));
```
```
ALTER mytable ADD [UNIQUE] INDEX [indexName] ON(columnname(length));
```
### 删除
```
DROP INDEX [indexName] ON mytable;
```
### 查看
```
SHOW INDEX FROM table_name G
```
## 5. 哪些情况需要创建索引
1. 主键自动建立唯一索引
2. 频繁作为查询的条件的字段应该创建索引
3. 查询中与其他表关联的字段,外键关系建立索引
4. 频繁更新的字段不适合创建索引 因为每次更新不单单是更新了记录还会更新索引,加重IO负担
5. Where条件里用不到的字段不创建索引
6. 单间/组合索引的选择问题,who?(在高并发下倾向创建组合索引)
7. 查询中排序的字段,排序字段若通过索引去访问将大大提高排序的速度
8. 查询中统计或者分组字段
## 6. 哪些情况不要创建索引
1. 表记录太少
2. 经常增删改的表
3. 数据重复且分布平均的表字段,因此应该只为经常查询和经常排序的数据列建立索引。
注意,如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果。
## 7. 性能分析
### 7.1 Explain
使用: Explain + SQL语句
结果
![](https://img.kancloud.cn/ad/ac/adacbfaf9b680b78e78cccc586598a9a_1093x101.png)
作用:
1. 表的读取顺序 id 字段
2. 数据读取操作的操作类型 select_type
3. 哪些索引可以使用 possible_keys
4. 哪些索引被实际使用 key
5. 表之间的引用 ref
6. 每张表有多少行被优化器查询 rows
### 7.2 Explain 结果介绍
#### 7.2.1 ID 表的读取顺序 *
select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序
1. id相同,执行顺序由上至下
![](https://img.kancloud.cn/d1/46/d146ecdbd433c1eb7550e63c9d3b00e7_778x282.png)
2. id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行
![](https://img.kancloud.cn/2f/5d/2f5db341c3ea75569a602464f9d48d2e_802x310.png)
3. id相同不同,同时存在
![](https://img.kancloud.cn/fd/66/fd66a3d1d6b789fd6e3c3b69727693b6_829x298.png)
#### 7.2.2 select_type
数据读取操作的操作类型
1. SIMPLE 简单的select查询,查询中不包含子查询或者UNION
2. PRIMARY 查询中若包含任何复杂的子部分,最外层查询则被标记为 PRIMARY
3. SUBQUERY 在SELECT或者WHERE列表中包含了子查询
4. DERIVED 在FROM列表中包含的子查询被标记为DERIVED(衍生)MySQL会递归执行这些子查询,把结果放在临时表里。
5. UNION 若第二个SELECT出现在UNION之后,则被标记为UNION;
若UNION包含在FROM子句的子查询中,外层SELECT将被标记为:DERIVED
6. UNION RESULT 从UNION表获取结果的SELECT
7.
#### 7.2.3 table
#### 7.2.4 type
![](https://img.kancloud.cn/30/02/3002de22ed0ee283baa415cd35cea28a_755x93.png)
从最好到最差依次是
system > const > eq_ref > ref > range > index > ALL
一般达到range, 最好能达到ref
1. system 表只有一行记录(等于系统表),这是const类型的特例,平时不会出现,这个也可以忽略不计
2. const 表示通过索引一次就找到了,const用于比较primary key或者unique索引。因为只匹配一行数据,所以很快。如将主键至于where列表中,MySQL就能将该查询转换为一个常量
3. eq_ref 唯一性索引,对于每个索引键,表中只有一条记录与之匹配,常见于主键或唯一索引扫描
4. ref 非唯一索引扫描,返回匹配某个单独值的所有行。本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体
5. range 只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引一般就是在你的where语句中出现了between、<、>、in等的查询这种范围扫描索引扫描比全表扫描要好,因为他只需要开始索引的某一点,而结束语另一点,不用扫描全部索引
6. index Full Index Scan,index与ALL区别为index类型只遍历索引树。这通常比ALL快,因为索引文件通常比数据文件小。(也就是说虽然all和index都是读全表,但index是从索引中读取的,而all是从硬盘中读的)
7. all FullTable Scan,将遍历全表以找到匹配的行
#### 7.2.5 possible_keys
显示可能应用在这张表中的索引,一个或多个。
查询涉及的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用
#### 7.2.5 key *
实际使用的索引。如果为null则没有使用索引
查询中若使用了覆盖索引,则索引和查询的select字段重叠
#### 7.2.6 ref
显示索引那一列被使用了,如果可能的话,是一个常数。那些列或常量被用于查找索引列上的值
![](https://img.kancloud.cn/32/1e/321e90f2d469220ac0694594c83f0396_843x201.png)
#### 7.2.7 rows *
根据表统计信息及索引选用情况,大致估算出找到所需的记录所需要读取的行数
#### 7.2.8 Extra
1. Using filesort 说明MySQL 会对数据使用一个外部的索引排序, 而不是按照表内的索引顺序进行读取. MySQL 无法利用索引完成的排序操作称为 "文件排序"
2. Using temporaty 使用了临时表保存中间结果, 常见于排序 和分组查询
3. Using Index 效率高
## 8. 索引优化
1. 全值匹配我最爱
2. 最佳左前缀法则 如果索引了多例,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列。带头大哥不能死,中间兄弟不能断
3. 不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描
4. 存储引擎不能使用索引中范围条件右边的列
5. 尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select*
6. mysql在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描
7. is null,is not null 也无法使用索引
8. like以通配符开头('$abc...')mysql索引失效会变成全表扫描操作
9. 字符串不加单引号索引失效
10. 少用or,用它连接时会索引失效
## 9. 查询优化
### 9.1 永远小表驱动大表, 类似嵌套循环Nested Loop
![](https://img.kancloud.cn/69/ed/69ed6008d709c3a84471f0c509d5ad2a_1075x526.png)
![](https://img.kancloud.cn/b7/9d/b79d6b9bc31712a43f51c529a81e14b5_1192x146.png)
### 9.2 order by关键字优化
联合索引的各个排序列的排序顺序必须要一致
ORDER BY子句,尽量使用Index方式排序,避免使用FileSort方式排序
使用Index排序的两种情况
order by 语句使用索引最左前列
使用where子句与order by字句条件列组合满足索引最左前列
![](https://img.kancloud.cn/2d/07/2d0704c2d1ebe69556aa3605a7e417bc_720x487.png)
### 9.3 group by关键字优化
和order by 相似
## 10 slow_query_log 慢查询日志
默认是关闭的
开启: set global slow_query_log = 1 本次有效, 重启数据库就没用了, 长期开启要设置配置文件
Mysql 日志工具
![](https://img.kancloud.cn/39/6c/396cd248147f1cd67896e092bd1631b1_1019x493.png)
## 11 Mysql锁机制
### 11.1 锁的分类
从数据操作的类型(读、写)分
读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响, 此时无法修改数据
写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁。
从对数据操作的颗粒度
表锁
行锁
页锁(前俩锁之前, 了解即可)
### 11.2 表锁(偏读)
偏向MyISAM存储引擎,开销小,加锁快,无死锁,锁定粒度大,发生锁冲突的概率最高,并发最低
![](https://img.kancloud.cn/30/7e/307e1d7a5689754a2a0334f3e9e01f9a_1249x512.png)
### 11.3 行锁(偏写)
偏向InnoDB存储引擎,开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION);二是采用了行级锁
#### 间隙锁危害
![](https://img.kancloud.cn/f2/39/f2399bb45cc86d9177e1d9b41ff7154f_1120x289.png)
## 如何锁定一行
![](https://img.kancloud.cn/b1/7f/b17f3a29d782a661078f27fc4735d8d1_1138x405.png)
- 学习地址
- MySQL
- 查询优化
- SQL优化
- 关于or、in、not in、!=等走不走索引的说明
- 千万级数据查询优化
- MySQL 深度分页问题
- 嵌套循环 Block Nested Loop 导致索引查询慢
- MySQL增加日志统计表优化各种日志表的统计功能
- MySQL单机读写QPS(性能)优化
- sqlMode 置 select 的值可以比 group 里的多
- drop、delete、truncate的区别
- 尚硅谷MySQL数据库高级学习笔记
- MySQL架构
- 事务部分
- MySQL知识点
- mysql索引
- Linux docker安装 mysql 8.0.25
- docker 安装mysql 5.7
- mysql Field ‘xxx’ doesn’t have a default value
- mysql多实例
- docker中的sql文件导入
- mysql进阶知识
- mysql字符集
- 连接的原理
- redo日志
- InnoDB存储引擎
- InnoDB的数据存储结构
- B+树索引
- 文件系统-表空间
- Buffer Pool
- 亿级数据导入到es
- MySQL数据复制
- MySQL缺少主键的表数据
- mysql update 其中更新的字段根据另一个更新字段作为条件去更新
- MySQL指定字段值排序(将指定值排在前面)
- 设置MySQL连接数、时区
- Navicat15右键删除数据刷新就又恢复了
- MySQL替换字段部分内容
- Java和MySQL统计本周本月本季和年
- 分页时order by 排序数据重复,丢失
- mysql同一张表根据某个字段删除重复数据
- mysqldump定时全量热备
- 专题总结
- 事务
- MySQL事务
- spring事务
- spring事务本类调用
- spring事务传播行为
- spring事务失效问题
- 锁和Transactional注解一块使用的问题
- 数据安全
- 敏感数据
- SQL注入
- 数据源
- XSS
- 接口设计
- 缓存设计
- 限流
- 自定义注解实现根据用户做QPS限流
- 架构
- 高可用
- Java
- Unsatisfied dependency expressed through field ‘baseMapper‘
- mybatisplus多数据源
- 单个字母前缀的java变量
- spring
- spring循环依赖解决
- 事务@Transactional
- yml 文件配置信息绑定到java工具类的静态变量上
- @Configuration @Component 区别
- springboot启动yml文件报错
- spring方法重试注解Retryable
- spring读取yml集合数据
- spring自定义注解
- 获取resource下的图片资源
- 手机号和电话号的正则验证
- 获取字符串中的数字
- mybatis
- mybatis多参数添加数据并返回主键
- 统一异常处理
- 分组校验
- Java读取Python json.dumps 函数保存的redis数据
- springboot整合springCache
- 若依mybatis值为null的字段没有返回
- 若依
- 接口白名单
- @JsonFormat时区问题
- RequestParam.value() was empty on parameter 0
- jdk8和hutool请求第三方的https报错
- springMVC
- springMVC与vue使用post传数组
- elementUI 时间组件报错问题
- vue具名插槽slot
- springboot配置maven的profiles(配置微服务多环境切换打包)
- resources 配置文件读取顺序
- Windows的cmd部署jar注意事项
- Java基础
- JUC(锁-并发-线程池)
- CAS
- Java 锁简介
- synchronized和Logk有什么区别?用新的ock有什么好处
- synchronized锁介绍
- CompletableFuture
- 多线程
- 线程池
- 集合类
- map见过的小问题
- 退出双层循环
- StringBuilder和StringBuffer核心区别
- 日志打印
- 打印log日志
- log日志文件生成配置
- 日期时间
- 时间戳转为时间
- 并发工具
- 连接池
- http调用
- 内网访问天地图
- 判等问题
- 数值计算
- null问题
- 异常处理
- 文件IO
- 序列化
- 内存溢出OOM
- 子线程的错误, 全局异常处理捕获不到
- vue同一个项目访问多个不同ip地址接口
- Autowired注解导入为null
- shiro
- UnavailableSecurityManagerException错误
- Windows服务器80端口被占用
- java图片增加水印
- springcloud
- Feign方法配置错误导致jar包启动失败
- feign调用超时
- 定时任务quartz
- JavaPOI导出Excel
- 合并行和列
- 设置样式
- 设置背景色
- docker
- Linux 安装
- docker命令
- docker网络
- docker数据卷
- dockerfile
- docker安装ping命令
- docker-compose
- docker-compose文件内容介绍
- Linux关闭docker开机启动
- jar打包为镜像
- 迁移docker容器存储位置
- Nginx
- Linux在线安装Nginx
- nginx.conf 核心配置文件
- vue 和 nginx 刷新页面会报404
- nginx 转发给三个集群的tomcat
- ServerName匹配规则
- Nginx负载均衡策略
- location 匹配规则
- Nginx 搭建前端调用后台接口的集群
- alias与root
- nginx 拦截 post 请求, 带参数转发到前端页面
- 防盗链配置
- Nginx的缓存
- 通用Nginx配置
- nginx配置文件服务器
- 后台jar包得不到正确ip,nginx代理时要处理
- 升级使用websocket协议
- 设置IP黑/白名单
- Redis
- 缓存数据一致性
- 内存淘汰策略
- Redis数据类型
- gmt6
- Linux安装GMT6
- GMT6配置中文
- GMT文件修改Windows版本到Linux版本
- 注意GMT不同字体导致符号不同的问题
- GMT绘制南海诸岛小图
- GMT生成中文图例
- elasticsearch
- 安装配置
- Linux安装配置elasticsearch7.6.2
- Linux 安装 kibana 7.6.2
- 安装7.6.2中文分词器
- docker 安装elasticsearch7.6.2
- 安装Logback7.6.2
- springboot使用
- 0. elasticsearch账号密码模式访问
- 1. 配置连接
- 2. 索引
- 3. 批量保存更新
- Result window is too large 10000
- elasticsearch 分词的字段做排序 fielddata, 设置fielddata=true 无效果
- elasticsearch 完全匹配查询(精确查询)
- 模糊搜索
- 日期区间查询
- 6.x基础知识
- 自定义词库
- elasticsearch集群
- 搜索推荐Suggester
- 查询es保存的数组
- 亿级mysql数据导入到es
- es 报错 ORBIDDEN/12/index read-only
- es核心概念
- es的分布式架构原理
- 优化大数据量时的ES查询性能
- canal
- 1. mysql的Binlog
- 2. Canal 的工作原理
- 3. canal同步es
- JVM
- 1 类的字节码
- 2. 类的加载
- JVM知识点
- Maven
- 依赖冲突
- xxl-job
- docker 安装配置 xxl-job
- idea
- springboot启动报错命令过长
- services统一启动微服务各模块
- 云服务器安装宝塔面板
- 突然出现启动或者运行特别慢
- 有导入依赖但是显示红色同时点击进去也有依赖
- Linux
- sh文件执行报错: command not found
- 使用vagrant安装虚拟机
- Linux 开启端口
- 开放端口
- 复制文件夹及其文件到另一个文件夹
- 两个服务器之间映射端口
- TCP协议
- 分层模型
- TCP概述
- 支撑 TCP 协议的基石 —— 首部字段
- 数据包大小对网络的影响 —— MTU 与 MSS 的奥秘
- 端口号
- 三次握手
- TCP 自连接
- 四次挥手
- TCP 头部时间戳
- 分布式
- 分布式脑裂问题
- 分布式事务
- 基础知识
- 实现分布式事务的方案
- 阿里分布式事务中间件seata
- 幂等性问题
- 其他工具
- webstorm git提交代码后project目录树不显示
- 消息队列
- 如何保证消费的顺序
- 数据结构
- 漫画算法:小灰的算法之旅