RDS MySQL 高效设计及性能调优(四)| 学习笔记

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 快速学习 RDS MySQL 高效设计及性能调优。

开发者学堂课程【RDS MySQL 高效设计及性能调优 :RDS  MySQL  高效设计及性能调优(四)】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/1209/detail/18176


RDS MySQL 高效设计及性能调优


七、RDS MySQL 使用经验

使用经验将列举七个比较常见的场景进行讲解、分享。

1. 主键设计原则

Inno DB 表是具值索引表,因此对于 Inno DB 而言的话,主键是比较有特殊意义的,因为 MySQL 的数据存储它是通过主键进行数据存储,通过主键直接定位到对应某一行数据的物理位置。所以 Inno DB 的任意一张表都应该有主键。如果没有显示的定义主键, Inno DB 也会选择比较符合条件的列作为主键:首先要判断一下表中是否有非空的唯一索引,如果有的话,他会当即作为主键;如果当表中存在多个非空的唯一索引,那么建表时第一个非空唯一索引是作为主键的。如果上述条件都不符合, Inno DB 会自动创建6字节大小的指针。 RDS MySQL 使用了参数去控制是否针对用户没有建 PK 的表,默认创建隐含主键。主键设计原则:第一,比较强烈推荐的使用整性类型,并且是无符号的一些递增长的作为主键, INT和 BIGINT ;但不推荐使用 VARCHAR 类型作为主键,也不要使用有业务含义的字段作为主键。

(1) 为什么会推荐用 INT 和 BIGINT 和无符号自增键作为主键?

因为 Inno DB 表前面也讲到了,它是聚集索引表,表中的数据按照主键顺序存放,如果主键是 AUTO_INCREMENT 是增长的,每次插入数据的话,就像第一页中的数据1 2 3 4 ~100,第二页101-104,当需要新增数据的时候,主键是递增长的,直接在103之后新增到104,直接插入到这个位置,它是顺序写入的过程。如果是非有序的话,先插入的10、100等,在接下来要插入S007主键对应的值,它需要在S001和S010中间去插入数据,这样插入数据的话会导致的新记录插入到合适位置而频繁移动数据,频繁移动会导致大量的碎片,碎片会影响查询的性能,到最后会越来越慢,所以一般是推荐是使用 AUT_INCREMENT 的递增长属性。如果不想用 AUT_INCREMENT 的话,就需要递增长的功能进行序列化,去递增长主键。还有无符号类型主要是增加支持范围。使用无符号之后,比如说BIGINT,它如果设置无符号,支持范围就会扩大更多的一倍。
所以总结来说,第一,主键被希望是递增长、有序的属性;如果使用无符号的话,能够扩大它的一倍,增大它自己的范围。

(2) 为什么不推荐使用 VARCHAR 作为主键?

在存储空间上 VARCHAR 类型占用n的变化类型, BIGINT 始终都占用八个字节。而且二级索引中包含了二级索引和主键列,主键越大,二级索引也会越大。 BP命中率因为数据量的增加会导致BP命中率下降, VARCHAR 会导致 PK 的非叶数节点数量增大,且非叶体节点一般都是热点数据,所以也会导致它的命中率下降。在插入的效率方面, VARCHAR 主键插入一般是随机插入,会引起比较大量的节点分裂,性能比较差, BIGINT 自增主键作为顺序插入,它的性能也会比较好。

下面是实验,在实验中可以看得到相同的数据量,这张表里边的方式、空间其实是不一样的, INT 类型用整型类型就是在1.9G, VARCHAR 类型它占用了2.3G。

接下来看一下这四个表哪个表会是更优的。

图片16.png

第一个表 user id是 VARCHAR 类型,刚刚说了不建议使用 VARCHAR 类型。第二个user id 是整型类型,但是它没有递增长,而且它的主键使用的是联合主键。第三个 id是无业务属性的,id包含了业务水平, id是无业务属性,而且是使用无符号,使用的 BIGINT ,而且是不为空,也是递增长的属性,是比较符合刚刚讲到的一些规则的。第四个表主要就是没有用到无符号类型。这两个表相比较的话,它的主键支持的范围会比小一倍。所以在这样子比较下来看的话,第三个表黄色的是比较最优的表结构设计。

2. Online DDL

Online DDL 对于日常的维护运维来说,是比较重要的一点。比如业务需要增加字段或者这些操作的时候,其实Online DDL 能在增加过程中不只是正常的 DML 的显露。现在从 MySQL 版本新版本也都支持 Online DDL 。像类型、Copy 表副本进行原表 Copy,类似的INPLACE 是在原表操作,避免复制表,这种场景下一般是允许并发 DML 的,一般是在开始和结束阶段会获取短暂的获取元数据锁。INSTANT 主要是修改原数据中的元数据,避免了复制表和元数据所、锁,操作速度也会非常快,只是针对表构建系统的变更,允许并发 DML ,这是从8.0版本后才开始支持。接下来是需要设置的锁,在 DDL 期间允许并发执行 DML 操作,不堵塞 DML 。 SHARED 是在 DDL 期间允许读,不允许写操作。 EXCLUSIVE 是 DDL 期间不允许任何操作。 DEFAULT 是 MySQL 自己判断使用的模式,要尽可能不堵塞 DML 操作。原生 Online DDL 不兼容的变更,可以使用 DMS 提供的无锁结构变更、pt-osc、gh-ost 等工具,pt工具是用于开源的。

判断是否允许并发 DML

可以在官网当中看对应的 Online DDL 的操作。

图片17.png

举例看一下主键的变更,增加主键的时候,其实是采用了 INPLACE 尽量避免复制表,可以允许 DML 的操作,它会创建新表,然后它会允许 DML 的操作等。可以根据表里面标识的 yes 和 no 进行判断。job 主键是不允许写操作的。再来看一下从键的索引,它其实是能够允许去做 DML 的操作。

3. 分页查询 

图片18.png

在 MySQL 当中查询一张表,然后 ORDER BY id,进行 limit,然后去翻页查询,我们可以知道在 MySQL 当中,翻页到最后性能会越来越慢,因为 MySQL 当中读取的是表前 m+n 条数据, m 越大性能也会越差,因为它所查询的数据量也越高。来看一下 select *from 的一张表和 id 大于 max id 、order by id 这种是适合顺序翻页的场景,每次记录上页,将 max id 带入到下一次查询当中,主要是减少 m 即前面已经查询过的数据,不要再去查询,从而减少这个查询的量。然后第二个 select 是适合于 id 进行分页,且没有 where 条件,将主键 id 放在子查询里面进行查询,原先查询主键在哪个值,然后再返回表里面去获取对应的这些id字段所需要的所有数据,这个可以提升产品效率。然后是带 where 条件的,同时也是在主键当中先将主键 id 查询出来,然后取出所需要对应的查询 id,然后在原表进行join连接,这种也会节约查询效率,所以说在 where 条件下创建二级索引可以加速查询效率。

来看一下实验

图片19.png

SELECT 的一张表,100-10查询效率是很快的,当查询1,000万的时候,这个速度立马降下来了。然后第三个是 select id大于1000,这个查询效率也会非常快,因为就直接定位到第一千万行的这条数据,之前1,000万行数据都不会进行查询,但是上一个的话会进行查询。
接下来来看一下带 where 条件的,带 where 条件的只查询id某值,然后 order by 取1,000万之后的10条数据,让他查询了2.48秒, select  进行整个 a 表所有数据和刚刚上面查询的结果进行 join,查询实际效率在两秒之内就查询出结果了,因为它主要时间还是耗在查询当中,然后再跟这个原表进行主键关联招引,然后反映出结果。第三个也是查询 id,然后返回这个值,然后进行 join 连接,这个是全角扫,下面这个它其实是进行了 where 条件的查询。可以看到有 where 条件,并且查所有数据,翻页查询的时候已经耗时了12.73秒。先在子查询中查询主键的结果再进行 join ,获取主键下面行的数据其实时间会节约到很多,可以看到提升了有差不多六倍。

4. 大标数据清理

图片20.png

大表数据的清理场景有历史数据的清理,通常是按照条件,如时间范围进行 delete 数据。但有两个问题,第一就是单次 delete 的行数过多,执行效率过慢会造成锁堵塞,事务过大主从复制延迟,影响线上业务;而且进行 delete 是不会直接立马释放磁盘空间。建议的话是使用这样的方案:根据主键最大值和最小值进行分批删除,并且根据时间处理。例如id大于最小值,然后最小值直接加1000,然后查询某个时间段每次只查询在1000行里边的主键数据进行删除,然后定期进行回收碎片。这样的话主要是降低每一次扫描的行数和删除的数量,然后进行优化。全表数据清理,建议是用 Truncate 进行整张表的删除,比如大表的话, Truncate 的话一定会发生 io 抖动,建议使用 RDS MySQL 异步清理的功能。

5. replace into 问题

image.png

replace into 的逻辑是先 delete ,再 insert 。它会产生一些问题。比如现在列出来的PK的冲突,此时如果 auto_increment 并不增长,主键 id 与元数据 id 保持一致;UK 冲突是 auto_increment 增长,主键 id 会增长,但 binlog 记录的是 update 语句。存在的问题是当 UK 冲突的时候,主库的 auto_increment 值增加,同时 binlog 记录的是 update ,当同步到备库的时候,备库执行 update 并不会改变在备库上的 auto_increment 的值,于是造成了备库在此场景上会存在不一致。我们进行一个测试,先进行数据插入,插入完之后进行 replace into,将 id=3 的值进行更新,更新的时候会发现它的主键递增长的 id从3变成了4,然后再去看 auto_increment 这个值已经变成了5。因为刚刚更新完它是4然后也变成5,看一下 binlog,其中会进入 update ,原来的这条数据做了变更,从3变成了4,然后 v 里边的3变成了1-10的值。然后再来看一下备库里边的表结构,它的这 auto_increment =4是没有做变更的,像主键的这个是=5,这个时候如果发生了主备切换,这个表就会变成主库,主库再插入一条数据的时候,将会从4开始递增长,这个时候就会出现主备冲突了。因为在这个表当主键它再插入一条数据的时候,主键 id 是会赋成4的的,而不是5。4的话在这个表已经变成了备库,备库中其实4已经存在了。主库写完成功之后,同步到备库的时候,备库就会变成了就会发生主键冲突。所以在 replace into 下,是不建议在生产业务上进行覆盖写入的。

6. RDS 只读实例复制延迟

RDS MySQL 只读实例延迟是基于原生的 binlog 复制技术一部分进行同步的,有异步复制或者半同步复制。在业务层面出现大事务等这种场景下,之后肯定会造成备库存在延迟,延迟会导致只读实例和主实例的数据出现不一致,如果业务去访问只读实例,数据存在不同步的话,可能会存在问题。延迟过大也会引起 binlog 的堆积,导致只读实例的空间会迅速被消耗。比如主实例当前正在产生大量的 binlog ,写入速度跟主库相比的话会比较慢,它所占用的空间会越来越大,也会导致只读实例因为空间满而被锁定。常见的延迟原因和解决方案:第一个,只读实例规格过小了,因为过小之后同步主库的速度的话会比较慢,会造成延迟。所以一般是建议只读实例规格避免较小,导致延时。推荐是跟只读实例大于或者等于主实例的配置;主实例的 TPS 过高,排查 TPS 可以考虑业务进行优化或者拆分,保证主实例的  TPS 不会导致只读实例出现延迟;主实例的大事务,建议将大事务拆分成小事务,例如 delete 语句,可能 delete 差不多几千万或者几十万的数据,这个数据已经算是大数,会造成锁堵塞,重复性更新的时候也会更新过慢。限制每次删除的数据量,然后将每一次的删除拆分为多次较小的删除,来提升单事务的执行效率。主库的 DDL 造成只读延迟的话,建议在业务低峰期进行,或者采用 DMS 无锁表的结构设计功能。无主键表建议是给每张表添加主键字段,因为在 RDS MySQL当中,目前已经支持对表添加隐式索引,但是对于历史创建的一些表需要进行重建才能支持隐式主键。

为什么推荐给每张表都建附件?因为主库里边它可能没有主键的表,可能去做一些动作的时候是大量一次性扫描,但是在备库就不是了,备库每同步一次,做一次执行,是每条数据进行更新,每条都会进行全表扫,就会导致备库的执行效率非常低,所以是非常建议每张表都要添加主键字段。

7. RDS MySQL 扩展性

图片22.png

RDS MySQL 扩展性可以有横向扩展,通过增加处理节点的方式来提高整体处理性能,例如 RDS MySQL 可以通过添加多个只读实例横向扩展能力,这种场景比较适合读多写少,大部分读可以接受偶尔的延迟。

纵向扩展项目可以增加当前处理节点的处理能力,提升整体的处理能力,像 RDS 进行规格的分配,然后提升读写能力。适用场景就是读写比较高,同时对读时效性也非常高。

垂直拆分:比如像上面讲的两种方式都无法满足业务的时候,可以考虑按照业务进行垂直拆分。例如可以按照会员、交易、库存、营销进行分实例进行存储,还要进行提供业务。
水平拆分: DRDS 支持自动水平拆分,提升数据存储容量、并发吞吐、复杂计算等方面的需求。它高度兼容 MySQL 协议和语法,接入成本也会比较低。这种场景比较适合超高并发,大规模的数据存储,互联网在线事务类的业务,数据不断扩充,急需更强计算能力在线事务型数据库。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
3月前
|
存储 SQL 关系型数据库
RDS DuckDB技术解析一:当 MySQL遇见列式存储引擎
RDS MySQL DuckDB分析实例以​列式存储与向量化计算​为核心,实现​复杂分析查询性能百倍跃升​,为企业在海量数据规模场景下提供​实时分析能力​,加速企业数据驱动型决策效能。​​
|
6月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
2月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
|
2月前
|
关系型数据库 分布式数据库 数据库
阿里云数据库收费价格:MySQL、PostgreSQL、SQL Server和MariaDB引擎费用整理
阿里云数据库提供多种类型,包括关系型与NoSQL,主流如PolarDB、RDS MySQL/PostgreSQL、Redis等。价格低至21元/月起,支持按需付费与优惠套餐,适用于各类应用场景。
|
2月前
|
SQL 关系型数据库 MySQL
Mysql数据恢复—Mysql数据库delete删除后数据恢复案例
本地服务器,操作系统为windows server。服务器上部署mysql单实例,innodb引擎,独立表空间。未进行数据库备份,未开启binlog。 人为误操作使用Delete命令删除数据时未添加where子句,导致全表数据被删除。删除后未对该表进行任何操作。需要恢复误删除的数据。 在本案例中的mysql数据库未进行备份,也未开启binlog日志,无法直接还原数据库。
|
2月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供高性价比、稳定安全的云数据库服务,适用于多种行业与业务场景。
|
2月前
|
关系型数据库 MySQL 数据库
云时代MySQL:RDS与自建数据库的抉择
在云计算时代,选择合适的数据库部署方案至关重要。本文深入对比了AWS RDS与自建MySQL的优劣,帮助您在控制权、运维成本和业务敏捷性之间找到最佳平衡点。内容涵盖核心概念、功能特性、成本模型、安全性、性能优化、高可用方案及迁移策略,为您提供全面的决策参考。
|
3月前
|
关系型数据库 MySQL 程序员
从自建MySQL到阿里云RDS:程序员的数据库减负革命
如果你正在为自建MySQL数据库的高成本运维发愁,为凌晨三点的主从同步故障告警而崩溃,为开发团队频繁索要新测试库的要求感到窒息——是时候开启一场数据库的自我救赎了。 程序员更需构建"技术敏锐度+工程落地能力+跨域协作"的三维竞争力,通过创建技术组合形成差异化优势。企业应建立持续学习机制,提供AI沙盒环境促进技术转化。
|
6月前
|
存储 关系型数据库 MySQL
【免费动手教程上线】阿里云RDS MySQL推出大容量高性能存储:高性能本地盘(最高16TB存储空间)、高性能云盘(最高64TB存储空间)
阿里云RDS MySQL提供高性能本地盘与高性能云盘等存储方案,满足用户大容量、低延迟需求。高性能本地盘单盘最大16TB,IO延时微秒级;高性能云盘兼容ESSD特性,支持IO性能突发、BPE及16K原子写等能力。此外,阿里云还提供免费动手体验教程,帮助用户直观感受云数据库 RDS 存储性能表现。
|
7月前
|
负载均衡 算法 关系型数据库
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL集群架构负载均衡故障排除与解决方案
本文深入探讨 MySQL 集群架构负载均衡的常见故障及排除方法。涵盖请求分配不均、节点无法响应、负载均衡器故障等现象,介绍多种负载均衡算法及故障排除步骤,包括检查负载均衡器状态、调整算法、诊断修复节点故障等。还阐述了预防措施与确保系统稳定性的方法,如定期监控维护、备份恢复策略、团队协作与知识管理等。为确保 MySQL 数据库系统高可用性提供全面指导。

推荐镜像

更多