最基本的原因是访问的数据太多.

6.2.1 是否向数据库请求了不需要的数据

  • MySQL 服务器会有额外开销
  • 增加网络开销
  • 消耗应用服务器的 CPU 和内存资源

典型案例:

  • 查询不需要的记录
  • 多表关联时返回全部列
  • 总是取出全部列
  • 重复查询相同的数据

6.2.2 MySQL 是否在扫描额外的记录

衡量查询开销的三个指标:

  • 响应时间
  • 扫描的行数
  • 返回的行数

这三个指标会记录到 MySQL 的慢日志中.

响应时间

响应时间 = 服务时间 + 排队时间

  • 服务时间: 数据库处理这个查询真正花的时间
  • 排队时间: 服务器因等待某些资源而没有真正执行查询的时间
    • I/O
    • 行锁

估算响应时间:

image.png

扫描的行数和返回的行数

理想情况下扫描的行数和返回的行数应该是相同的:

  • 一般在1:1和10:1之间

扫描的行数和访问类型

在 EXPLAIN 语句中的 type 列反映了访问类型:

从慢到快:

  • 全表扫描
  • 索引扫描
  • 范围扫描
  • 唯一索引查询
  • 常数引用

索引让 MySQL 以最高效, 扫描行数最少的方式找到需要的记录.

在有索引的列上进行过滤:

image.png

删除索引的对比:

image.png

  • Using Where 表示 MySQL 将通过 WHERE 条件来筛选存储引擎返回的记录

MySQL 有三种使用 WHERE 条件的方式, 从好到坏:

image.png

优化扫描大量行但只返回少数行的查询:

image.png