MySQL调优(六)查询优化


1 查询速度慢的原因

  查询速度慢的原因有很多,比如网络、IO、CPU、上下文切换、系统调用、生成统计信息(profile和performance schema等)、锁等待。

2 数据访问优化

  查询性能低下的主要原因是访问的数据太多,某些查询不可避免地需要筛选大量的数据,我们可以通过减少访问数据量的方式进行优化。需要确认应用程序是否在检索大量超过需要的数据,以及MySQL服务器层是否在分析大量超过需要的数据行。
  向数据库请求了不需要的数据有以下情况:

  • 查询不需要的记录,我们常常会误以为MySQL会只返回需要的数据,实际上MySQL却是先返回全部结果再进行计算,在日常的开发习惯中,经常是先用select语句查询大量的结果,然后获取前面的N行后关闭结果集,优化方式是在查询后面添加limit。
  • 多表关联时返回多个表的全部列。
  • 查询时使用select *。
  • 重复查询相同的数据,可以使用缓存解决。

3 执行过程优化

3.1 查询缓存

  在解析一个查询语句之前,如果查询缓存是打开的,那么mysql会优先检查这个查询是否命中查询缓存中的数据,如果查询恰好命中了查询缓存,那么会在返回结果之前会检查用户权限,如果权限没有问题,那么mysql会跳过所有的阶段,就直接从缓存中拿到结果并返回给客户端。需要注意的是,MySQL从8.0开始已经放弃了缓存。

3.2 查询优化器

  当语法树没有问题之后,相应的要由优化器将其转成执行计划,一条查询语句可以使用非常多的执行方式,最后都可以得到对应的结果,但是不同的执行方式带来的效率是不同的,优化器的最主要目的就是要选择最有效的执行计划。
  优化方式一般有基于成本的优化(CBO)和基于规则的优化(ROB),MySQL使用的是基于成本的优化器,在优化的时候会尝试预测一个查询使用某种查询计划时的成本,并选择其中成本最小的一个。其优化类型有以下几种:

  • 重新定义关联表的顺序,数据表的关联并不总是按照在查询中指定的顺序进行,决定关联顺序是优化器很重要的功能。
  • 将外连接转化成内连接,内连接的效率要高于外连接。
  • 使用等价变换规则,MySQL可以使用一些等价变化来简化并规划表达式。
  • 优化count()、min()、max(),索引和列不可为空通常可以帮助MySQL优化这类表达式,例如:要找到某一列的最小值,只需要查询索引的最左端的记录即可,不需要全文扫描比较。
  • 预估并转化为常数表达式,当mysql检测到一个表达式可以转化为常数的时候,就会一直把该表达式作为常数进行处理。
  • 索引覆盖扫描,当索引中的列包含所有查询中需要使用的列的时候,可以使用覆盖索引。

4 特定类型的查询优化

  • 优化关联查询:当表A和表B使用列C关联的时候,如果优化器的关联顺序是B、A,那么就不需要再B表的对应列上建上索引,没有用到的索引只会带来额外的负担,一般情况下来说,只需要在关联顺序中的第二个表的相应列上创建索引。
  • 确保任何的group by和order by中的表达式只涉及到一个表中的列,这样mysql才有可能使用索引来优化这个过程。
  • 优化子查询:子查询的优化最重要的优化建议是尽可能使用关联查询代替。
  • 优化limit分页:在很多应用场景中我们需要将数据进行分页,一般会使用limit加上偏移量的方法实现,同时加上合适的orderby 的子句,如果这种方式有索引的帮助,效率通常不错,否则的化需要进行大量的文件排序操作,还有一种情况,当偏移量非常大的时候,前面的大部分数据都会被抛弃,这样的代价太高。要优化这种查询的话,要么是在页面中限制分页的数量,要么优化大偏移量的性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值