# SQL 优化

+ SQL 业务逻辑优化 
  + TiDB Dashboard 慢查询
  + TiDB Dashboard SQL 语句分析
  + TiDB Server 日志中的 expensive query
+ 执行计划优化
  + 优化器没有选择最优执行计划
  + 未创建必要索引
  + 执行计划准确，但内存占用高

-------------------------------------------------------------

需要跟业务开发侧的相关人员确认返回大量数据的合理性，以及是否可在满足业务要求的情况下，缩小数据范围。

- SQL 执行计划优化
通过前面 SQL 优化的相关课程，我们已经学习了 TiDB SQL 优化相关的内容，故此处不再赘述，只做简要的说明，如有疑问可再次学习 SQL 优化的课程。
  - 步骤 1：通过 TiDB Dashboard 慢查询以及 SQL 语句分析功能模块，可查看集群中内存占用大的 SQL 的执行计划，以及执行计划的个数等信息
  - 步骤 2：通过步骤 1，基本可以判断执行计划是否准确性

    - 优化器选择了效率低的执行计划
      - 可通过下面的方式干预优化器选择成本低，但访问效率高的执行计划：
        - Hint，需要改写 SQL，对前端业务有一定的入侵性
        - SPM，在不修改 SQL 语句的情况下干预执行计划的选择，自动捕获绑定、自动演进绑定等
      - 检查统计信息的健康度
        - SQL 执行计划中，如果出现了 pesudo 关键字时，表示无可用统计信息，需要对表或索引进行 analyze
        - 如果统计信息健康度在 100%，那么可能是 CBO 优化器成本估算出现了不准确的情况，可使用 SQL Binding 在非改写 SQL 的情况下，固定该 SQL 的执行计划

    - 未创建必要索引
      - 根据业务访问目标表的行为特点，创建必要的索引，在提高 SQL 访问效率的同时，减少非必要的数据返回，降低内存占用

    - 执行计划准确，但内存占用高
      - 在统计信息，以及优化器选择均准确的情况下，也有可能出现内存占用高的情况，如 Hash Join 的 inner 表占用内存比较大，此时可考虑 Merge Join
      - Merge Join 是一种特殊的 Join 算法。当两个关联表要 Join 的字段需要按排好的顺序读取时，适用 Merge Join 算法。Merge Join 占用的内存要远低于 Hash Join，但 Merge Join 不能并发执行，并且执行时间会更久。当数据量太大，或系统内存不足时，建议尝试使用。
