高性能MySQL之查询性能优化(四)

版权声明:YETA https://blog.csdn.net/qq_28958301/article/details/89453488

高性能:库表结构优化、索引优化、查询优化。

1. 为什么查询速度会慢

如果要优化查询,实际上要优化其子任务,要么消除其中一部分子任务,要么减少子任务的执行次数,要么让子任务运行得更快。

通常来说,查询的生命周期大致可以按照顺序来看:从客户端,到服务器,然后在服务器上进行解析,生成执行计划,执行,并返回结果给客户端。

在完成这些任务的时候,查询需要在不同的地方花费时间,包括网络、CPU计算、生成统计信息和执行计划、锁等待等操作,尤其是向底层存储引擎检索数据的调用操作,这些调用需要在内存操作、CPU操作和内存不足时导致的I/O操作上消耗时间。根据存储引擎不同,可能还会产生大量的上下文切换以及系统调用。

2. 慢查询基础:优化数据访问

查询性能低下最基本的原因是访问的数据太多。对于低效的查询,通过下面两个步骤来分析总是很有效的:

  • 确认应用程序是否在检索大量超过需要的数据,这通常意味着访问了太多的行,但有时候也可能是访问了太多的列;
  • 确认MySQL服务器层是否在分析大量超过需要的数据行。

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

2.1.1 查询不需要的记录

一个常见的错误是常常会误以为MySQL会只返回需要的数据,实际上MySQL却是先返回全部结果集再进行计算。最简单有效的解决方法是在这样的查询后面加上LIMIT。

2.1.2 多表关联时返回全部列

正确的方式应该是只取需要的列。

2.1.3 总是取出全部列

SELECT *会让优化器无法完成索引覆盖扫描这类优化,还会为服务器带来额外的I/O、内存和CPU的消耗。

扫描二维码关注公众号,回复: 5975020 查看本文章

2.1.4 重复查询相同的数据

当初次查询的时候将这个数据缓存起来,需要的时候从缓存中取出。

2.2 MySQL是否在扫描额外的记录

在确定查询只返回需要的数据以后,接下来应该看看查询为了返回结果是否扫描了过多的数据。对于MySQL,最简单的衡量查询开销的三个指标是:

  • 响应时间
  • 扫描的行数
  • 返回的行数

这三个指标都会记录到MySQL的慢日志中,所以检查慢日志记录是找出扫描行数过多的查询的好办法。

2.2.1 响应时间

响应时间是两个部分之和:服务时间和排队时间。

服务时间是指数据库处理这个查询真正花了多长时间。

排队时间是指服务器因为等待某些资源而没有真正执行查询的时间,可能是等I/O操作完成,也可能是等待行锁等。

当看到一个查询的响应时间的时候,确定这个时间是否是一个合理的值。了解这个查询需要哪些索引以及它的执行计划是什么,然后计算大概需要多少个顺序和随机I/O,再用其乘以在具体硬件条件下一次I/O的消耗时间,最后把这些消耗都加起来,就可以获得一个大概参考值来判断当前响应时间是不是一个合理的值。

2.2.2 扫描的行数和返回的行数

理想情况下扫描的行数和返回的行数应该是相同的,但是关联查询中,服务器必须要扫描多行才能生成结果集中的一行。

2.2.3 扫描的行数和访问类型

在EXPLAIN语句的type列反应了访问类型,速度从慢到快,扫描行数从多到少依次是:全表扫描、索引扫描、范围扫描、唯一索引扫描、常数引用等。

一般MySQL能够使用如下三种方式应用WHERE条件,从好到坏依次为:

  • 在索引中使用WHERE条件来过滤不匹配的记录,这是在存储引擎层完成的;
  • 使用索引覆盖扫描(Extra列中出现Using index)来返回记录,直接从索引中过滤不需要的记录并返回命中的结果,这是在MySQL服务器层完成的,无须再回表查询记录;
  • 从数据表中返回数据,然后过滤不满足条件的记录(Extra列中出现Using where),这是在MySQL服务器层完成的,需要先从数据表读出记录然后过滤。

如果发现查询需要扫描大量的数据但只返回少数的行,那么可以这样去优化:

  • 使用索引覆盖扫描;
  • 该表库表结构;
  • 重写这个复杂查询。

3. 重构查询的方式

猜你喜欢

转载自blog.csdn.net/qq_28958301/article/details/89453488
今日推荐