SQL 优化|学习笔记

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 快速学习 SQL 优化

开发者学堂课程【云数据库优化经典案例:SQL 优化】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/67/detail/1159


SQL 优化

内容简介:

一、分页优化案例

二、子查询优化案例

三、SQL 优化最佳实践


一、分页优化案例

SQL 优化主要是两个案例,第一个是分页优化案例。

图片5.png

上图就是一个案例,可以看到上述数据库,它的 IOPS 是百分之百,但是 CPU、QPS 和连接数值都非常低。因为处理了 IO,它也是被 SQL 占用的。这时去看数据库到底运营行怎样的 SQL ?可以看到数据库运行的 SQL 已经有51秒,一直在 Sending data,这个 SQL其实就是商家导订单的一个 SQL,在分页去导订单。卖家可能是一个非常大的卖家,订单非常多,所以去通过分页去导订单。其实可以看到 SQL 执行的非常慢,数据库中堆积非常多的 SQL。那 SQL 是否可以优化?由上图可以看到此 SQL,前提条件是表中已经有 sellerId 和  gmt_ modified  的索引。

图片6.png

普通写法:

select * from buyer where sellerid=100 limit 10000o , 5000

普通 limit M,N 的翻页写法,在越往后翻页的过程中速度越慢,原因是 mysql 会读取表中的前 M+N 条数据,M 越大,性能就越差。

这个  SQL 其实是一个普通分页写法,在普通的翻页写法里可能会有的问题;普通limit M,N 的翻页写法存在一个问题,就是越往后翻页的过程中速度越慢,因为 MySQL  翻译时不需要把前面 limit 中第一个数据(m)读出来,然后再去读(n)真要去翻译函数的数据,所以随着 M 越大,就是前面翻页第一位的数字越大,后面的性能可能就会越来越差。在以前 BBS 论坛较火的时候,那时其实很多论坛就是翻页写法,采用 limit M,N 的写法。如果论坛前面的几个帖子是热帖,它前面几页访问都是非常快的,但是到后面随着越往后翻页,性能就越来越慢。问题就是最终的 SQL 写法采用了普通写法。随着M,也就是翻译的第一个数字越大,性能会越来越差,那这个 SQL 写法如何优化?

优化写法:

select t1.* from buyer t1.

(select id from buyer sellerid=100 limit 100000,5o00) t2where t1.id=t2.id;

在淘宝以前前台的翻页,比如商品详情页面,其实也有类似的翻译,普通的翻页写法是不能在淘宝前端的,写法上必须经过优化的,那下面这个写法就是淘宝 SQL 翻页的规范。这个规范是怎样实施的?我们可以看到 SQL 首先是查出 id ,这个 id  是真正要去翻译一个5000行的 id。那这里有什么好处?就是说查询这个 id,真正要翻译的。取得5000行的数据,这个数据是在索引里查询,因为这个表里已经有对应 id 的索引,所以查询这5000行 id 时不需要查询前面的10万行数据,先查询5000行 id,再和主表做关联。优化后的写法和原写法的代价有所区别,原来需要查询前面的十万行数据,再去查需要的五千行数据,优化后只需查询这5000行 id 再和原表做关联。这就体现出了分页的优势。需要注意的就是,子查询里的 id 一定在索引里,覆盖索引去查询,不能回表。

注意:需要在 t 表的 sellerid 字段上创建索引,id 为表的主键create index ind_sellerid on buyer(sellerid);

图片7.png

上图是一个分页优化的案例,上面是原写法,下面是优化后的写法,先查 id 再去和主表关联,这样他的执行时间就可以从60秒降低到0.2秒。所以我们可以看到前面这种普通写法查询了大量无效数据,通过优化后的写法扫描的真实的数据大量减少。

这就是我们 SQL 优化里的第一个案例,就是分页优化,这是淘宝数据库开发里很重要的一个点。


二、子查询优化案例

下面一个就是子查询的一个案例,这个也是一个非常典型的案例。

典型子查询:

SELECT first_name

FROM employees

WHERE emp_no IN

(SELECT emp_no FROM salaries_2000 WHERE salary = 5000);

MySQ L的处理逻辑是遍历 employees 表中的每一条记录,代入到子查询中中去

改写子查询:

SELECT first_name

FROM employees emp,

(SELECT emp_no FROM salaries_2000 WHERE salary = 5000) sal

WHERE emp.emp_no = sal.emp_no;

在2014年时,一个大项目中把系统从 orcle 迁到 mysql 上面,时间是在周六,选在周六是因为访客人数相对少一点,系统迁到 mysql 后,当时的系统是5.5,在迁移后,发现 MySQL 集群全部挂掉了,经过分析,发现集群出现 SQL 堆积的问题,因为 MySQL 里处理子查询和 orcle 里处理子查询是完全不一样的原理,导致了当时集群瘫痪这样一个问题。在2010年去 IOE 的时候,也是从大型的 orcle 迁移到 mysql 里面。

可以看到子查询的原理。这个 SQL 是查询薪水为5000块的员工名字,所以,他先去查薪水表,再和 employee 表做关联。所以,这个子查询,正常逻辑是把5000块钱薪水的员工号查出再和主表 employee 表做关联。但在 MySQL 里面,它的优化器支持嵌套循环,通过 A 表驱动 B 表,如果 A 表非常大,那么这个循环次数就非常多,所以这个时候 mysql 的优化器决定了sql 执行的的顺序,在执行 SQL 的时候,从外部employee 表循环去带对应值到子查询里面所以这个 SQL 不是同我们想象的执行顺序,查出5000块薪水的员工号再和 employee 表做关联。当外部的驱动表非常大就会导致遍历到子查询里的次数非常多进而导致性能下降。所以当时把 SQL 进行了改造,把子查询数据提出来,先算出结果级,把子查询往前提和 employee 表放成同一个位置,这样 SQL 的执行速度就快了。

所以在遇到这样的子查询时,要做 SQL 的改写,这里要特别注意。那这个问题通过一个改写,从1200秒缩短为0.1秒,执行速度迅速提升。子查询是在5.1、5.5版本中存在一个较大风险,需要把这个子查询改写为关联,5.6版本后,则不需要再改写子查询。


三、SQL优化最佳实践

1、分页优化

采用高效的 Limit 写法,避免分页查询给数据库带来性能影响

2、子查询优化

子查询在5.1,5.5版本中都存在较大风险,将子查询改为关联使用 Mysql 5.6 的版本,可以避免麻烦的子查询改写

3、查询需要的字段

避免用 SELECT* 查询所有字段数据,只查询需要的字段数据

分页优化,也需要一个高效的分页写法,避免普通的写法给数据库带来较低的性能。第三,经常有很多 SQL 做一个 SELECT * 操作,然后再做一个外层,在包一层做 COUNT * 写法,此时 MySQL 就不得不把 SELECT * 子查询中的结果查出来。比如在外面再套一层条件,那外面的条件就不能只传递到查询里面,进而导致性能的低价低效。所以第一个不要去省 * ,只需要查询需要查询的字段;第二个就是尽量把子查询外面的条件带入到查询里面。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
SQL 存储 关系型数据库
如何巧用索引优化SQL语句性能?
本文从索引角度探讨了如何优化MySQL中的SQL语句性能。首先介绍了如何通过查看执行时间和执行计划定位慢SQL,并详细解析了EXPLAIN命令的各个字段含义。接着讲解了索引优化的关键点,包括聚簇索引、索引覆盖、联合索引及最左前缀原则等。最后,通过具体示例展示了索引如何提升查询速度,并提供了三层B+树的存储容量计算方法。通过这些技巧,可以帮助开发者有效提升数据库查询效率。
144 2
|
19天前
|
SQL 缓存 监控
大厂面试高频:4 大性能优化策略(数据库、SQL、JVM等)
本文详细解析了数据库、缓存、异步处理和Web性能优化四大策略,系统性能优化必知必备,大厂面试高频。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:4 大性能优化策略(数据库、SQL、JVM等)
|
28天前
|
SQL 存储 缓存
如何优化SQL查询性能?
【10月更文挑战第28天】如何优化SQL查询性能?
88 10
|
27天前
|
SQL 存储 缓存
SQL Server 数据太多如何优化
11种优化方案供你参考,优化 SQL Server 数据库性能得从多个方面着手,包括硬件配置、数据库结构、查询优化、索引管理、分区分表、并行处理等。通过合理的索引、查询优化、数据分区等技术,可以在数据量增大时保持较好的性能。同时,定期进行数据库维护和清理,保证数据库高效运行。
|
2月前
|
SQL 资源调度 分布式计算
如何让SQL跑快一点?(优化指南)
这篇文章主要探讨了如何在阿里云MaxCompute(原ODPS)平台上对SQL任务进行优化,特别是针对大数据处理和分析场景下的性能优化。
|
2月前
|
SQL 监控 数据库
慢SQL对数据库写入性能的影响及优化技巧
在数据库管理系统中,慢SQL(即执行缓慢的SQL语句)不仅会影响查询性能,还可能对数据库的写入性能产生显著的不利影响
|
2月前
|
SQL 关系型数据库 PostgreSQL
遇到SQL 子查询性能很差?其实可以这样优化
遇到SQL 子查询性能很差?其实可以这样优化
99 2
|
2月前
|
SQL 存储 数据库
慢SQL对数据库写入性能的影响及优化技巧
在数据库管理系统中,慢SQL(即执行缓慢的SQL语句)不仅会影响查询性能,还可能对数据库的写入性能产生显著的不利影响
|
2月前
|
SQL 数据处理 数据库
SQL语句优化与查询结果优化:提升数据库性能的实战技巧
在数据库管理和应用中,SQL语句的编写和查询结果的优化是提升数据库性能的关键环节
|
2月前
|
SQL 存储 数据库
慢SQL对数据库写入性能的影响及优化策略
在数据库管理系统中,慢SQL(即执行缓慢的SQL语句)不仅会影响查询性能,还可能对数据库的写入性能产生不利影响