# 优化数据访问

  1. 确认应用程序是否在检索大量超过需要的数据
    • 查询不需要的记录
    • 多表关联时返回全部列
    • 总是取出全部列
    • 重复查询相同的数据
  2. 确认 MySQL 服务器层是否在分析大量超过需要的数据行
    • 响应时间,服务时间 + 排队时间
    • 扫描的行数和返回的行数
    • 扫描的行数和访问类型

# 重构查询的方式

  • 一个复杂查询还是多个简单查询
  • 切分查询
  • 分解关联查询

# 查询执行的基础

查询执行路径

  1. 客户端 / 服务器通信协议
    • 半双工模式,同一时刻,要么服务器向客户端发送数据,要么客户端向服务器发送数据,不能同时发生。
  2. 查询缓存
  3. 查询优化处理
    • 语法解析器和预处理器,将 SQL 解析成树,然后检查是否合法
    • 查询优化器,转化成执行计划
      • 重新定义关联表的顺序
      • 将外连接转化成内连接
      • 使用等价变换规则
      • 优化 COUNT ()、MIN () 和 MAX ()
      • 预估并转化为常数表达式
      • 覆盖索引扫描
      • 子查询优化
      • 提前终止查询
      • 等值传播
      • 列表 IN () 的比较
  4. 查询执行引擎
  5. 返回结果给客户端

# 查询优化器的局限性

  • 关联子查询,优化器实现不是很好,有时候可能不是按照我们所理解的那样去优化,要实际测试效果
  • UNION 的限制,如果只取部分结果集,可分别在每个子语句中先 LIMIT,再整体 LIMIT,减小临时表数量
  • 索引合并优化
  • 等值传递
  • 并行执行
  • 哈希关联
  • 松散索引扫描
  • 最大值和最小值优化
  • 同一个表上查询和更新

# 查询优化器的提示

  • HIGH_PRIORITY 和 LOW_PRIORITY
  • DELAYED
  • STRAIGHT_JOIN
  • SQL_SMALL_RESULT 和 SQL_BIG_RESULT
  • SQL_BUGGER_RESULT
  • SQL_CACHE 和 SQL_NO_CACHE
  • SQL_CALC_FOUND_ROWS
  • FOR UPDARE 和 LOCK IN SHARE MODE
  • USE INDEX、INGNORE INDEX 和 FORCE INDEX

# 优化特定类型的查询

  • 优化 COUNT () 查询
  • 优化关联查询
  • 优化子查询
  • 优化 GROUP BY 和 DISTINCE
  • 优化 GROUP BY WITH ROLLUP
  • 优化 LIMIT 分页
  • 优化 SQL_CALC_FOUND_ROWS
  • 优化 UNION 查询