MySQL 是否在扫描额外的记录
衡量查询开销的指标
- 响应时间
- 扫描的行数
- 返回的行数
它们大致反映了MySQL在内部执行查询时,需要访问多少数据,可以大概推算出查询运行的时间
响应时间
响应时间 = 服务时间 + 排队时间
使用快速上限估计法,来查询响应时间
扫描的行数和返回的行数字
分析查询时,查看该查询扫描的行数很有帮助,理想情况下扫描的行数和返回的行数应该是相同的
但例如在做一个关联查询时,服务器必须要扫描多行才能生成结果集中的一行
扫描的行数和访问类型
有些访问方式可能需要扫描很多行才能返回一行结果,有些访问方式可能无须扫描就能返回结果
在EXPLAIN语句中的type列反映了访问类型
- 全表扫描
- 范围扫描
- 唯一索引查询
- 常数引用
EXPLAIN的结果也显示MySQL预估需要访问10行数据
删掉索引之后,变成了一个全表扫描
MySQL通过WHERE条件筛选存储引擎返回的记录
以下三种方式应用WHERE条件,从好到坏依次为
- 在索引中使用WHERE条件过滤不匹配的记录,这是在存储引擎层完成的
- 使用索引覆盖扫描(Extra列中出现了Using index)返回记录,直接从索引中过滤不需要的记录返回命中结果
- 从数据表中返回数据,过滤不满足条件的记录Extra列中出现了Using index)
然后并不是说增加索引就能让扫描的行数等于返回的行数
查询数量需要读取几千行数据,但仅返回几百行,没有什么索引能够让这样的查询减少需要扫描的行数
查询需要扫描大量的数据但只返回少数的行
- 使用索引覆盖扫描,把所有需要用的列都放到索引中,存储引擎便无须回表扫描
- 改变库表结构,例如使用单独的汇总表
- 重写复杂查询,让MySQL优化器能够以更优化的方式执行这个查询
论读书
睁开眼,书在面前 闭上眼,书在心里
睁开眼,书在面前 闭上眼,书在心里