MySQL性能优化(六):常见优化SQL的技巧

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: SQL 优化技巧是性能优化的重中之重。

image.png

作者:xcbeyond

博客:https://xcbeyond.cn/ 公众号:程序猿技术大咖


在面对不够优化、或者性能极差的 SQL 语句时,我们通常的想法是将重构这个 SQL 语句,让其查询的结果集和原来保持一样,并且希望 SQL 性能得以提升。而在重构 SQL 时,一般都有一定方法技巧可供参考,本文将介绍如何通过这些技巧方法来重构 SQL。


一、分解 SQL

有时候对于一个复杂 SQL,我们首先想到的是是否需要将一个复杂 SQL 分解成多个简单 SQL,来完成相同业务处理结果。


在以前,大家总是强调需要数据库层来完成尽可能的工作,这也就不难理解在一些老的产品、项目中时常会看见很多超级复杂、超级长的 SQL 语句,这样做的逻辑在以前认为多次交互,在网络带宽、程序与数据库间网络通信等方面是一件代价很高的事情。然后在现在,无论是带宽还是延迟,网络速度比以前要快的很多,多次交互也没有太大的问题。即使在一个通用服务器上,也能够运行每秒超过 10 万的查询,所以运行多个小查询现在已经不是大问题了。


复杂 SQL 的分解,在面对超级复杂 SQL 语句时,性能提升尤为明显。所以,在面对超级复杂 SQL 语句,并且存在性能问题时,推荐分解为小查询来进行优化。


不过,在应用设计的时候,如果一个查询能够胜任并且不会产生性能问题,这时完全可以用一个稍微复杂的SQL来完成的,倘若再死板的强制拆分成多个小查询是不明智的。


在当今很多高性能的应用系统中,都是极力推荐使用单表操作,然后将单表查询结果在应用程序中进行关联,以满足复杂业务的查询需求。 一个 SQL 可以搞定事情,为何要分开来写,而且还得在应用程序中多次执行 SQL 查询,再进行结果集的关联,这到底为什么要这么做呢?


乍一看,这样做复杂不说而且没有什么好处,原本一条查询,这样却变成了多条查询。事实上,这样分解有如下的优势:


  • 让缓存更高效。在应用程序中,可以很方便地缓存单表查询结果对应的结果对象,便于后续任何时候可以直接从结果对象中获取数据。
  • 分解查询后,执行单个查询可以减少表锁的竞争。
  • 在程序应用层做关联,可以更容易对数据库进行拆分,更容易做到高性能和可扩展。
  • 单表查询效率高于多表复杂查询。
  • 减少冗余记录的查询。在程序应用层关联,意味着对于某条记录应用只需要查询一次,而在数据库中做关联查询,则可能需要重复地访问一部分数据记录。从这点来看,这样的重构还可能减少网络和内存的消耗。


二、查询切分

有时候对于一个大查询,即:结果集很大的查询,我们需要采用“分而治之”的思想,将大查询切分为小查询,每个查询功能完全一样,只是完成一小部分,每次只返回一小部分查询结果。通俗来讲,就是对 where 条件的过滤范围进行切分,每次只查询其中一部分数据,即:类似于分页查询。


这样做,不管对于 SQL 查询本身,还是对于上层业务来说,都是很小的开销。最典型的的案例就是分页查询,目前各类框架都有了很好的支持,如:MyBatis 等,只需在实际使用时稍加留意就可避免。


三、执行计划

使用执行计划 EXPLAIN 关键字,可以使我们知道 MySQL 是如何执行 SQL 语句的,这样可以帮助我们分析我们的查询语句或是表结构的性能瓶颈。EXPLAIN 的查询结果还会告诉我们索引主键是如何被利用的,数据表是如何被搜索或排序的等等。


语法格式是:


EXPLAIN SELECT语句;


通过执行计划结果,将会指导我们进一步来重构 SQL 语句,如:增加索引、调整索引顺序、避免使用某些函数等等。


关于执行计划,后续章节将会单独详细讲解。


四、遵守原则

在平时写 SQL 时,养成好的习惯,多加留意,很大程度上就会避免一些 SQL 性能问题。汇总如下:


  • 永远为每张表设置一个 ID 主键。
  • 避免使用 SELECT *
  • 为搜索字段建立索引。
  • 在 Join 表的时候使用对应类型的列,并将其索引。
  • 尽可能的使用 NOT NULL
  • 越小的列会越快。
  • 当只要一行数据时使用 LIMIT 1
  • 操作符的优化,尽量不采用不利于索引的操作符,目的就是为了避免全表扫描。
    1)in not in 慎用,尽量用 between 代替 in,用 not exists 代替 not in
    2)is nullis not null 慎用
    3)!=<> 操作符能不用就不用,否则将使引擎放弃使用索引而进行全表扫描。
  • ……


五、使用查询缓存

当有很多相同的查询被执行了多次的时候,这些查询结果会被放入一个缓存中,这样后续的相同查询就不用操作而直接访问缓存结果了。


MySQL 查询缓存保存查询返回的完整结果。当查询命中该缓存,MySQL 会 like 返回结果,跳过了解析、优化和执行截断。


这是提高查询性能最有效的方法之一,而且这是被 MySQL 引擎处理的,通常 MySQL 默认是不开启查询缓存的,需要手动开启。


查询缓存对应用程序是完全透明的。应用程序无需关心 MySQL 是通过查询返回的还是实际执行返回的结果。事实上,这两种方式执行的结果是完全相同的。换句话说,查询缓存无需使用任何语法。


随着现在的通用服务器越来越强大,查询缓存被发现是一个影响服务器扩展性的因素。它可能成为整个服务器的资源竞争单点,在多核服务器上还可能导致服务器僵死。所以大部分时候应该默认关闭查询缓存,如果查询缓存作用很大的话,可以配置个几十兆的小缓存空间。(在选择时,需要进行权衡)


关于查询缓存有如下参数可供配置:

  • query_cache_type
    是否打开查询缓存。可以设置 OFFONDEMANDDEMAND 表示只有在查询语句中明确写入 sql_cache 的语句才放入查询缓存。
  • query_cache_size
    查询缓存使用的总内存空间,单位是字节。这个值必须是 1024 的整倍数,否则实际分配的数据会和指定的大小有区别。
  • query_cache_min_res_unit
    在查询缓存中分配内存块时的最小单位。
  • query_cache_limit
    缓存的最大查询结果。如果查询结果大于这个值,则不会被缓存。因为查询缓存在数据生成的时候就开始尝试缓存数据,所以只有当结果全部返回后,MySQL 才知道查询结果是否超出限制。


关于查询缓存,后续章节将会单独详细讲解。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3天前
|
存储 算法 关系型数据库
MySQL连接的原理⭐️4种优化连接的手段性能提升240%🚀
MySQL连接的原理⭐️4种优化连接的手段性能提升240%🚀
|
3天前
|
SQL canal 运维
MySQL高可用架构探秘:主从复制剖析、切换策略、延迟优化与架构选型
MySQL高可用架构探秘:主从复制剖析、切换策略、延迟优化与架构选型
|
3天前
|
存储 SQL 关系型数据库
掌握高性能SQL的34个秘诀🚀多维度优化与全方位指南
掌握高性能SQL的34个秘诀🚀多维度优化与全方位指南
|
3天前
|
存储 算法 关系型数据库
MySQL怎样处理排序⭐️如何优化需要排序的查询?
MySQL怎样处理排序⭐️如何优化需要排序的查询?
|
3天前
|
SQL 存储 关系型数据库
5分钟搞懂MySQL半连接优化⭐️多种半连接的优化策略
5分钟搞懂MySQL半连接优化⭐️多种半连接的优化策略
|
3天前
|
SQL 存储 关系型数据库
MySQL的3种索引合并优化⭐️or到底能不能用索引?
MySQL的3种索引合并优化⭐️or到底能不能用索引?
|
3天前
|
存储 关系型数据库 MySQL
MySQL的优化利器⭐️Multi Range Read与Covering Index是如何优化回表的?
本文以小白的视角使用通俗易懂的流程图深入浅出分析Multi Range Read与Covering Index是如何优化回表
|
4天前
|
存储 SQL 关系型数据库
MySQL的优化利器⭐️索引条件下推,千万数据下性能提升273%🚀
以小白的视角探究MySQL索引条件下推ICP的优化,其中包括server层与存储引擎层如何交互、索引、回表、ICP等内容
MySQL的优化利器⭐️索引条件下推,千万数据下性能提升273%🚀
|
11天前
|
SQL 关系型数据库 MySQL
【MySQL系列笔记】常用SQL
常用SQL分为三种类型,分别为DDL,DML和DQL;这三种类型的SQL语句分别用于管理数据库结构、操作数据、以及查询数据,是数据库操作中最常用的语句类型。 在后面学习的多表联查中,SQL是分析业务后业务后能否实现的基础,以及后面如何书写动态SQL,以及完成级联查询的关键。
167 6
|
11天前
|
SQL 关系型数据库 MySQL
【MySQL-4】简述SQLの通用语法及4种基本语句介绍(DDL/DML/DQL/DCL)
【MySQL-4】简述SQLの通用语法及4种基本语句介绍(DDL/DML/DQL/DCL)