Skip to content

Menu
Menu

衡量SQL查询的三个指标

Posted on 2022年11月12日2022年11月26日 by zhezimi

对于MySQL,最简单的衡量查询开销的三个指标如下:

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

没有哪个指标能够完美地衡量查询的开销,但它们大致反映了MySQL在内部执行查询时需要访问多少数据,并可以大概推算出查询运行的时间。这三个指标都会被记录到MySQL的慢日志中,所以检查慢日志记录是找出扫描行数过多的查询的好办法。

响应时间

响应时间是两部分之和:服务时间和排队时间。服务时间是指数据库处理这个查询真正花了多长时间。排队时间是指服务器因为等待某些资源而没有真正执行查询的时间—-可能是等待I/O操作完成,也可能是等待行锁,等等。遗憾的是,我们无法把响应时间分到上面这些部分,除非有什么办法能够逐个测量这些消耗,但这个很难做到。最常见和重要的是I/O等待和锁等待,但是实际情况更加复杂。实际上I/O等待和锁等待非常重要,因为它们对于性能有着至关重要的影响。

在不同类型的应用压力下, 响应时间并没有一致的规律或者公式,例如存储引擎的锁(表锁,行锁),高并发资源竞争,硬件响应等诸多因素都会影响响应时间。

当你看到一个查询的响应时间时,首先就要问问自己,这个响应时间是否是一个合理的值。

扫描的行数和返回的行数

分析查询时,查看该查询扫描的行数是非常有帮助的,这在一定程序上能够说明该查询需要的数据效率高不高。对于那些糟糕的查询,这个指标可能还不够完美,因为并不是所有行的访问代价都是相同的,较短的行的访问速度更快,内存中的行比磁盘中的行的访问要快得多。

理想情况下扫描的行数和返回的行数应该是相同的,但实际上这种情况并不多。例如,在做一个join查询时,服务器必须要扫描多行才能生成结果集中的一行,扫描的行数与返回的行数的比率通常很低,一般在1:1到10:1之间,不过有时候这个值也可能非常大。

扫描的行数和访问类型

在评估查询开销的时候,需要考虑从表中找到某一行数据的成本。MySQL有好几种访问方式可以查找并返回一些结果。有些访问方式可能需要扫描很多行才能返回一行结果,也有些访问方式可能无须扫描就能返回结果。

EXPLAIN语句中的type列反映了访问类型。访问类型有很多种,从全表扫描到索引扫描,范围扫描,唯一索引查询,常数引用等。这里列出的这些,速度从慢到快,扫描的行数从多到少。

如果你没办法找到合适的访问索引,那么最好的解决方法就是增加一个合适的索引。索引让MySQL以最高效,扫描行数最少的方式找到需要的记录。

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

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

如果发现查询需要扫描大量的数据但只返回少数行,那么通常可以尝试下面的技巧去优化它:

  • 使用索引覆盖扫描,把所有需要用的列都放在索引中,这样存储引擎就无需回表获取对应行就可以返回结果了
  • 改变库表结构,例如,使用单独的汇总表
  • 重写这个复杂的查询,例如,拆成多条sql,然后让程序来组装数据

参考书籍

《高性能MySQL》

相关文章

  • 如何删除大表

  • 备份与恢复

  • 字符集设置

  • 数据类型:JSON

  • 事务ID分配时间

发表评论 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

近期文章

  • 排查网络故障常用命令
  • PHP-FPM异常问题
  • RabbitMQ 1:介绍
  • 观察者模式
  • 装饰者模式

近期评论

没有评论可显示。

分类

  • cdn
  • css
  • docker
  • git
  • http
  • javascript
  • linux
  • mysql
  • nginx
  • php
  • RabbitMQ
  • 代码规范
  • 性能
  • 正则表达式
  • 网络协议
  • 设计模式
© 2025 | Powered by Minimalist Blog WordPress Theme