mysql查询优化

优化数据访问

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

  • 查询不需要的记录
  • 多表关联是返回全部列
  • 总是取出全部列 ,尽量不要使用select *,去除全部列,可能会使优化器无法完成索引覆盖扫描这种优化.还会为服务器带来额外的IO,内存和cpu开销.
  • 重复查询相同的数据.可以将经常用到的数据放在缓存里,避免重复查询数据库

    是否在扫描额外的数据

    确定了查询的数据列后,还应该看看查询是否为了返回结果是否扫描了过多的数据.对于mysql,最简单的衡量开销指标有三个:
    • 响应时间 包括服务时间(就是查询时间)和排队时间(也就是等待锁或者等待其他I/O完成的时间)
    • 扫描行数
    • 返回行数
      对于查询最好的就是扫描行数/返回行数在1:1到10:1之间
      可以尝试使用索引覆盖扫描,把所有需要的列放入索引中,这样存储引擎就可以不需要回表就可以返回列,或者重写查询.以更优的方式查询结果

重构查询的方式

  • 考虑是用一个大的查询还是用很多个小的查询.因为在实际应用中,如果一个查询很大的话可能会导致锁住整个表,耗尽系统资源,阻塞后面的查询.因此有时候可以使用多个小的查询来返回结果,最后在把小的查询组合起来.
  • 分解关联查询,因为每个数据库都有自己的缓存,如果分解大的查询可以更好的应用自己的缓存

mysql查询执行过程

  1. 客户端向服务器发送一条消息(这是半双工的,意思是同一时间只有一方能够发送数据)
  2. 服务器先查询缓存,如果缓存命中,直接返回给客服,否则进入下一阶段
  3. 服务端进行sql解析,预处理,在根据优化器生成对应的查询计划
  4. 调用存储引擎API查询数据,
  5. 将结果返回给客户端.

mysql能处理的优化类型

  • 重新定义关联表的顺序
  • 将外部连接转化程内部连接
  • 使用等价变换规则, 比如 5=5 and a>5 换成 a>5
  • 优化count(),min(),max(),如果在索引列找最小值,直接搜索最左边的值
  • 覆盖索引查询,如果索引的列包含所有要查询的列的时候就无须在回表查询
  • 子查询优化
  • 提前终止查询: 比如使用limit语句的时候,发现语句够了,就会直接终止
  • 列表in的比较,在mysql中,会把在in中的数据进行排序,然后在根据二分查找来查询,明显提高了查找速度.