服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Mysql - 什么时候 MySQL 查询会变慢?

什么时候 MySQL 查询会变慢?

2023-06-07 01:00未知服务器之家 Mysql

前面几篇文章和小伙伴们聊的基本上都是从索引的角度去优化 MySQL 查询,然而,索引创建的好,并不意味着查询就一定快,影响查询效率的因素特别多,今天我们就来聊一聊这些可能影响到查询的因素。 1. 查询流程 开始今天的内

前面几篇文章和小伙伴们聊的基本上都是从索引的角度去优化 MySQL 查询,然而,索引创建的好,并不意味着查询就一定快,影响查询效率的因素特别多,今天我们就来聊一聊这些可能影响到查询的因素。

1. 查询流程

开始今天的内容之前,先来和小伙伴们大概捋一捋 MySQL 的查询流程。我们来看如下一张图:

什么时候 MySQL 查询会变慢?

  1. 首先,用户通过连接器和服务端之间建立通信连接,这个说白了就是一个 Socket 通信,用户名/密码的校验,用户权限的判断等等,都是在这个连接器中完成的。
  2. 接下来需要对我么传入的 SQL 进行解析,这块跟代码的执行流程其实差不多,先做词法分析,识别出各种关键字,然后再做语法分析,语法分析就是根据 MySQL 的各种语法规则,去判断 SQL 是否满足语法规则。
  3. 接下来就是查询优化器出场,查询优化器就是分析要执行的 SQL,判断应该选择哪一个索引,包括在多表联合查询的时候,各个表的连接顺序也是由查询优化器来决定的,优化器执行完毕之后,会生成查询执行计划,我们平时通过 explain 关键字查看到的就是这个。
  4. 最后就是执行器了,执行器调用搜索引擎提供的具体接口去获取数据。

这张图大家大概有个印象,在后续的 MySQL 查询和优化中,很多东西就容易理解了。

接下来我们就来看看什么情况下查询会变慢。

2. 查询了不需要的记录

数据按需取用。有时候我们会忽略多拿数据对查询性能的影响,然而优化是一个锱铢必较的事情,需要多少数据就查询多少,要尽量避免数据库查询 100 条,结果前端只展示 10 条这种情况。如有需要,可以通过 limit 来限制数据库查询出来的数据总量。

如果在查询的时候使用了唯一性索引的话,那么查询到记录之后 MySQL 就停止扫描了;但是如果查询的时候使用的是非唯一性索引的话,那么扫描到第一条记录之后,还会继续向后扫描,直到扫描到第一条不满足条件的记录为止,对于这种情况,如果我们确定查询的结果只有一条,则可以通过 limit 进行限制,设置 limit 1,那么扫描到第一条满足条件的记录之后,就不会继续扫描了。

3. 返回需要的列

查询的时候尽量避免 select *,这个问题在之前的文章中松哥其实和大家聊过了,因为很多时候我们在前端其实并不需要使用到那么多字段,可能只是为了查询简单,直接来一个 select *,有时候列数和数据总量都比较少的时候,这么写也看不出来性能明显的差异,但是当列数和数据量大了,那么 select * 带来的影响就会比较大了。

特别是有的时候多表联合查询,如果用 select * 就会把多张表的查询结果拼接到一起,那么此时查询结果的列数就会成倍增加。

在前面的文章中,松哥也和大家提到过覆盖索引,如果索引设计得当,那么在查询的时候可以通过覆盖索引来提高查询的性能,但是如果使用了 select * 那么大概率是用不了覆盖索引了。

4. 恰到好处的缓存

这里举一个 TienChin 项目的例子,用户登录成功之后,在后续的流程中,经常会用到当前登录用户的信息,如果每次都去数据库查询,每次查询返回结果都是一致的,没有必要,此时我们可以将用户信息存入到 Redis 缓存中,需要的时候从 Redis 中提取就可以了。

在项目中,对于这些需要多次频繁查询,且每次查询返回结果一样的数据,都可以选择将之存入到缓存中以提高查询性能。

5. 关注扫描行数

在查询的时候,我们可以通过 explain 来查看执行计划,执行计划中有一个指标是扫描行数,如下图中的 rows,这个就表示查询优化器预估要扫描多少行记录,filtered 则表示预估满足条件的比例。

什么时候 MySQL 查询会变慢?

一般在单表查询时候我们并不会特别关注 filtered 字段,在多表联合查询的时候会比较关注该字段的值。

6. 关注扫描类型

这一条实际上就是让大家关注前面查询计划中的 type 字段的值,type 字段的取值有很多种,例如常见的 index、ALL、range、const 以及 ref,还有一些不常见的如 system、eq_ref、fulltext、ref_or_null、index_merge、unique_subquery、index_subquery 等,每一种都代表了不同的查询计划,再结合查询计划中的 Extra 字段中的值,我们大致上可以将查询分为三种类型:

  1. 直接调用存储引擎层进行查询,查询结果在 MySQL Server 层不需要额外处理,直接返回给客户端即可。
  2. 直接从索引中过滤出来想要的值并返回给客户端,这种时候,过滤虽然发生在 MySQL Server 层,但是由于不需要回表,效率也还过得去。
  3. 从数据表中查询到相应的记录,然后在 MySQL Server 层进行过滤,过滤的同时可能还需要回表,此时效率就会低一些。

延伸 · 阅读

精彩推荐
  • Mysqlmysql 不能插入中文问题

    mysql 不能插入中文问题

    当向mysql5.5插入中文时,会出现类似错误 ERROR 1366 (HY000): Incorrect string value: '\xD6\xD0\xCE\xC4' for column ...

    MYSQL教程网5722019-11-25
  • MysqlMySQL 数据备份与还原的示例代码

    MySQL 数据备份与还原的示例代码

    这篇文章主要介绍了MySQL 数据备份与还原的相关知识,本文通过示例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下...

    逆心2972019-06-23
  • Mysql解决MySQl查询不区分大小写的方法讲解

    解决MySQl查询不区分大小写的方法讲解

    今天小编就为大家分享一篇关于解决MySQl查询不区分大小写的方法讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起...

    Veir_dev5592019-06-25
  • MysqlMySQL锁的知识点总结

    MySQL锁的知识点总结

    在本篇文章里小编给大家整理了关于MySQL锁的知识点总结以及实例内容,需要的朋友们学习下。...

    别人放弃我坚持吖4362020-12-14
  • MysqlERROR: Error in Log_event::read_log_event()

    ERROR: Error in Log_event::read_log_event()

    ERROR: Error in Log_event::read_log_event(): read error, data_len: 438, event_type: 2 ...

    MYSQL教程网6412020-03-13
  • Mysql详解MySQL中的分组查询与连接查询语句

    详解MySQL中的分组查询与连接查询语句

    这篇文章主要介绍了MySQL中的分组查询与连接查询语句,同时还介绍了一些统计函数的用法,需要的朋友可以参考下 ...

    GALAXY_ZMY5442020-06-03
  • Mysql浅谈mysql 树形结构表设计与优化

    浅谈mysql 树形结构表设计与优化

    在诸多的管理类,办公类等系统中,树形结构展示随处可见,本文主要介绍了mysql 树形结构表设计与优化,具有一定的参考价值,感兴趣的小伙伴们可以参...

    小码农叔叔5242021-11-16
  • MysqlMySQL数据库varchar的限制规则说明

    MySQL数据库varchar的限制规则说明

    本文我们主要介绍了MySQL数据库中varchar的限制规则,并以一个实际的例子对限制规则进行了说明,希望能够对您有所帮助。 ...

    mysql技术网4192019-11-23