索引

方案

image.png

## 数据库SQL优化
### 前置知识
#### 选择索引
- 外键
- WHERE 中的列
- ORDER BY 的列(减少数据库排序消耗)
- 关联条件列
- 区分度高的列
#### EXPLAIN(分析SQL执行计划核心工具)
- type:查询访问类型(优先级:system > const > eq_ref > ref > range > index > ALL)
  - system:仅1行数据(系统表),最优
  - const:主键/唯一索引匹配行,效率极高
  - eq_ref:多表关联时,主键/唯一索引匹配行
  - ref:非唯一索引匹配多行
  - range:索引范围扫描(如between、in),避免范围过大
  - index:扫描全索引树(未命中数据索引)
  - ALL:全表扫描(无索引可用,需优先优化)
- possible_keys:MySQL认为可能适用的索引(仅候选集)
- key:SQL实际使用的索引(为空则未走索引)
- rows:预估需要扫描的行数(数值越小越好)
- filtered:符合条件的记录占扫描行数的比例(越高越好)
#### 大表定义变更
- 表锁会阻塞所有操作
- 方式1:停机变更
- 方式2:业务低谷变更
- 方式3:创建新表→数据迁移→双写
### 优化方案
- 覆盖索引:减少回表
- 优化COUNT(*)
  - 预估值
  - 额外维持总数计数(使用Canal的高级方案)
- 索引提示优化:非良好实践
- 用 WHERE 替换 HAVING:注意SQL执行顺序
- 优化分页中的偏移量

索引的代价

索引并不是没有代价的,它会消耗很多的系统资源。

索引本身需要存储起来,消耗磁盘空间。

在运行的时候,索引会被加载到内存里面,消耗内存空间。

在增删改的时候,数据库还需要同步维护索引,引入额外的消耗

索引引发异常

增删索引在晚上无人的时候操作,或者使用无锁变更

优化方式

硬件资源优化:换更大更强的机器。 操作系统优化:调整操作系统的某些设置。 服务器 / 引擎优化:也就是针对数据库软件本体进行优化,比如说调整事务隔离级别。在 MySQL 里面还可以针对不同的引擎做优化,比如说调整 InnoDB 引擎的日志刷盘时机。SQL 优化:针对的就是 SQL 本身了。

1.减少磁盘 IO,这个又可以说是尽量避免全表扫描、尽量使用索引以及尽量使用覆盖索引。 2.减少内存 CPU 消耗,这一部分主要是尽可能减少排序、分组、去重之类的操