高性能 MySQL(八):通过优化数据访问,来解决慢查询

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 前面几篇文章中介绍了如何设计最优的库表结构,以及如何建立最好的索引,这些对于高性能来说是必不可少的。但这还不够——还需要合理的设计查询。如果查询写得很糟糕,即使库表结构再合理、索引再合适,也无法实现高性能。

572f78222f941355a191d47a6fcc5734_image_auth_key=1686638014-bgmCV8o5kVmA99igPURgLH-0-54cf62ae8f13811b10adbfed9c848415&file_size=58402.png

大家好,我是水滴~~

前面几篇文章中介绍了如何设计最优的库表结构,以及如何建立最好的索引,这些对于高性能来说是必不可少的。但这还不够——还需要合理的设计查询。如果查询写得很糟糕,即使库表结构再合理、索引再合适,也无法实现高性能。


一、为什么查询速度会慢

如果把查询看作是一个任务,那么它由一系列子任务组件,每个子任务都会消耗一定的时间。如果想要优化查询,实际上要优化其子任务,要么消除其中一些子任务,要么减少子任务的执行次数,要么让子任务运行得更快。

通常来说,一个查询的生命周期,按顺序大致分为:从客户端,到服务端,然后在在服务器上进行解析,生成执行计划,执行,并返回结果给客户端。其中“执行”可以认为是整个生命周期中最重要的阶段,这其中包括大量为了检索数据,而到存储引擎的调用,以及调用后的数据处理,包括排序、分组等。

在完成这些任务的时候,查询需要在不同的地方花费时间,包括网络,CPU 计算,生成统计信息和执行计划、锁等待(互斥等待)等操作,尤其是向底层存储引擎检索数据的调用操作。

在每一个消费大量时间的查询案例中,我们都能看到一些不必要的额外操作、某些操作被重复了很多次、某些操作执行得太慢等。优化查询的目的就是减少和消除这些操作所花费的时间。

二、优化数据访问

查询性能低下最基本的原因是访问的数据太多。大部分性能低下的查询都可以通过减少访问的数据量的方式进行优化。对于低效的查询,可以通过下面两个步骤来分析。

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

有些查询会请求超过实际需要的数据,然后这些多余的数据会被应用程序丢弃。这会给 MySQL 服务器带来额外的负担,并增加网络开销,另外也会消耗应用服务器的 CPU 和内存资源。

下面列出一些典型的案例:

1.1 查询不需要的记录

一个常见的案例是,当需要获取最新一条数据时,一些开发者会按时间倒序查询出所有数据,并返回给应用程序,然后应用程序再获取结果集中的第一条。

select * from student order by create_time desc;

最简单有效的解决方法是,在查询后面加上 LIMIT

select * from student order by create_time desc limit 1;

1.2 多表关联时返回全部列

比如我们要查出所有“软件工程2101班”的所有学生,下面写法是不推荐的:

SELECT
  * 
FROM
  student s
  INNER JOIN class c ON s.class_id = c.id 
WHERE
  c.NAME = '软件工程2101班';

该查询会返回这两个表的全部数据列。正确的方式应该像下面这样,只取需要的列:

SELECT
  s.* 
FROM
  student s
  INNER JOIN class c ON s.class_id = c.id 
WHERE
  c.NAME = '软件工程2101班';

1.3 总是取出全部列

每次看到select *的时候都需要用怀疑的眼光审视,是不是真的需要返回全部的列?很可能不是必需的。

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

当然,使用select *也并不总是坏事。在很多案例当中,这种方式能够提高相同代码片段的复用性,简化了开发。如果能够清楚这样做的性能影响,也是值得考虑的。

1.4 重复查询相同的数据

在一些情况下,需要不断地重复执行相同的查询,然后每次返回完全相同的数据。例如,在用户评论的地方需要查询用户头像的 URL,那么用户多次评论的时候,可能就会反复查询这个数据。像这种应用场景,一般通过缓存技术来避免重复查询相同的数据。

2. MySQL 是否在扫描额外的记录

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

2.1 响应时间

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

  • 服务时间是指数据库处理这个查询真正花了多长时间。
  • 排队时间是指服务器因为等待某些资源而没有真正执行查询的时间(例如等待 I/O 操作完成、等待行锁等等)

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

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

分析查询时,查看该查询扫描的行数是非常有帮助的。这在一定程度上能够说明查询的效率高不高。

较短的行的访问速度更快,内存中的行也比磁盘中的行的访问速度要快得多。

理想情况下,扫描的行数和返回的行数应该是相同的。但实际情况中这种“美事”并不多。

2.3 扫描的行数和访问类型

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

EXPLAIN语句中的type列反应了访问类型。访问类型有很多种:全表扫描、索引扫描、范围扫描、唯一索引查询、常数引用等。刚才列出的类型,速度是从慢到快,扫描的行数也是从小到大。

如果查询没有办法找到合适的访问类型,那么解决的最好办法通常就是增加一个合适的索引。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
18天前
|
SQL 关系型数据库 MySQL
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
118 9
|
23天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
61 18
|
22天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
22 7
|
21天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化与慢查询优化:原理与实践
通过本文的介绍,希望您能够深入理解MySQL索引优化与慢查询优化的原理和实践方法,并在实际项目中灵活运用这些技术,提升数据库的整体性能。
53 5
|
22天前
|
存储 关系型数据库 MySQL
mysql怎么查询longblob类型数据的大小
通过本文的介绍,希望您能深入理解如何查询MySQL中 `LONG BLOB`类型数据的大小,并结合优化技术提升查询性能,以满足实际业务需求。
84 6
|
1月前
|
SQL 关系型数据库 MySQL
mysql分页读取数据重复问题
在服务端开发中,与MySQL数据库进行数据交互时,常因数据量大、网络延迟等因素需分页读取数据。文章介绍了使用`limit`和`offset`参数实现分页的方法,并针对分页过程中可能出现的数据重复问题进行了详细分析,提出了利用时间戳或确保排序规则绝对性等解决方案。
|
2月前
|
关系型数据库 MySQL 数据库
GBase 数据库如何像MYSQL一样存放多行数据
GBase 数据库如何像MYSQL一样存放多行数据
|
2月前
|
关系型数据库 MySQL Java
MySQL索引优化与Java应用实践
【11月更文挑战第25天】在大数据量和高并发的业务场景下,MySQL数据库的索引优化是提升查询性能的关键。本文将深入探讨MySQL索引的多种类型、优化策略及其在Java应用中的实践,通过历史背景、业务场景、底层原理的介绍,并结合Java示例代码,帮助Java架构师更好地理解并应用这些技术。
57 2
|
2月前
|
SQL 关系型数据库 MySQL
【赵渝强老师】MySQL的慢查询日志
MySQL的慢查询日志用于记录执行时间超过设定阈值的SQL语句,帮助数据库管理员识别并优化性能问题。通过`mysqldumpslow`工具可查看日志。本文介绍了如何检查、启用及配置慢查询日志,并通过实例演示了慢查询的记录与分析过程。
184 3
|
存储 SQL 关系型数据库
慢查询与MySQL语句优化(下)
如果我们了解了Mysql中的索引原理之后,(详见探秘数据库 —— 事务 + InnoDB存储引擎),如何利用索引并对一些执行较慢的sql进行优化也是必要的,所以我们可以结合索引的原理来探究一下慢查询与优化的知识。
慢查询与MySQL语句优化(下)