如何从设计和规范上规避RDS性能问题?【阿里云MVP月度分享】

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 在初创型互联网公司中,开发们整天想的唯一一件事,就是“把功能做出来”;而当公司业务量逐渐上涨、甚至翻了好几番之后,最开始的程序上的问题,就一个接一个地暴露了出来。

在初创型互联网公司中,开发们整天想的唯一一件事,就是“把功能做出来”。而当公司业务量逐渐上涨、甚至翻了好几番之后,最开始的程序上的问题,就一个接一个地暴露了出来。
其中,最明显的,就是数据库的压力问题。下文提到的数据库,都指RDS for MYSQL

场景一:宽表

现象

开发在设计表结构的时候,很大程度上是在参考产品原型的设计。通常会把产品原型中,需要一起查询的条件、一起展示的字段,都放在同一张表中。而互联网公司的产品迭代又是非常快的,新功能层出不穷,开发没有时间重新梳理数据库结构,就盲目地在原来的表上增加冗余字段,为了使功能尽快开发完成。这就使得某些“老古董”的表,越来越宽,七八十个字段以上的大宽表越来越多。

建议

(1)单个InnoDB表的字段数,建议少于50个;
(2)大字段,例如:text、blob类型,考虑单独存放;

场景二:列表的行数查询

现象

在后台或者部分前端的功能中,常常会出现类似MIS系统的列表查询功能。一般这种功能,都是按照选定的查询条件,先查出行数,再按照分页规则查询出第一页的数据。于是,就出现了这样的几种情况:
(1)查询列表明细,是需要使用多表关联查询的。开发为了方便,直接把这个查询明细的“多表关联”的SQL拿过来,把select后边的字段改成count(*),就直接作为查询行数的SQL,甚至连order by都不去掉。而从业务上来说,查询行数的时候,只需要查询其中一张表就可以了;
(2)代码逻辑的设计不合理,导致某些开发,直接套用“首页”逻辑,查询后续每一页的时候,都重新查询了一遍行数;

建议

(1)增加SQL审核机制,不合规范的SQL不允许上线;
(2)增加代码审核机制;

场景三:查询不走索引

现象

很常见的情况是,某些表最开始的数据量很小,后来由于产品功能重心的调整,变成了大表。之前做好的程序、SQL、表结构却没有跟着调整。就出现了很多大表查询,没走索引,导致的慢查询。而慢查询堆积多了,整个数据库就瘫痪了,于是就出现了“次要业务拖累主要业务”的现象。

建议

(1)根据查询场景,设置合理的索引,组合索引优先;
(2)当组合索引和单字段索引同时存在时,建议删掉单字段索引,避免优化器做“无用功”;

场景四:线上数据和线下数据没有隔离

现象

这里说的线上数据,指的是直接面对广大用户的数据;线下数据,是面向公司内部客服、运营的后台系统用到的数据。后台系统由于工作职责的不同,会有各种各样的查询需求,有的可能会很大、很复杂,比如导出一整个月、一整个季度的数据。会直接导致数据的压力非常大,进而影响了整个数据库实例,导致线上系统发生故障。

建议

  • 线上数据的特点是:

    1. 访问量大;
    2. 每个用户只查自己的数据,可以命中索引;
    3. 查询条件简单;
    4. 返回条数少;
    5. 对响应时间要求极高;
    6. 对数据的时效性要求高;
  • 线下数据的特点是:

    1. 访问量小;
    2. 后台同事会查询整个平台的数据,不容易命中索引;
    3. 查询条件复杂;
    4. 返回条数大;
    5. 对响应时间要求不高;
    6. 对数据的时效性要求不是特别高;

综上,两类数据从各个方面都是完全不同的。要把线上数据和线下数据隔离开来。更新时,统一更新线上数据;查询时,线上查线上,线下查线下。线上数据通过DTS等实时数据同步的方式更新到线下。

场景五:过于依赖MYSQL,没有考虑其他的存储

现象

某些列表查询类场景,可能涉及到10~20个查询条件,而且检索数据量一般也很大。此时再使用MYSQL就比较吃力了,索引几乎无法覆盖。

建议

除了关系型数据库之外,我们有很多不同的数据存储的选择,比如:搜索引擎类、NOSQL类、时序类、缓存类,等等。应当根据不同的查询场景,选择最适合的数据存储方式。企图用MYSQL解决一切问题,是不明智的。

场景六:没有站在数据库的角度去思考

现象

比如,子查询。开发站在人类的角度思考问题,就会出现形如:

SELECT * FROM table1 WHERE id IN ( SELECT id FROM table2 );

这种子查询。而MYSQL在处理子查询的时候,是拿外层的每一条数据,去内层扫描,结果就是扫描了table1的行数 × table2的行数次。

建议

避免使用子查询,改为通过索引做表关联等方式;

场景七:直接在数据库中做计算

现象

部分开发会在SQL中写例如case whengroup by + count/sum等的计算。MYSQL擅长的是,数据的查询与存储,并不擅长做计算——虽然它可以做。导致出现了很多慢SQL。MYSQL只对查询做了优化,并没有对计算做优化。

建议

(1)group by + count/sum可以考虑进行预计算;
(2)case when可以在业务端或者前端进行;
(3)要有效利用每个工具最擅长做的事。

场景八:在索引字段上用函数

现象

部分表在bigint类型的、存放时间戳的字段上做了索引,而查询的条件是精确到天的。某些开发就会把SQL写成:

WHERE from_unixtime(create_timestamp) >= '2018-01-01'
AND from_unixtime(create_timestamp) < '2018-02-01'

这样。在索引字段上使用函数,索引就起不到作用,扫描数据的时候依然是全表扫描,并对每一行数据的create_timestamp做from_unixtime运算。

建议

如:

WHERE from_unixtime(create_timestamp) >= '2018-01-01'
AND from_unixtime(create_timestamp) < '2018-02-01'

这种场景,可以改为:

WHERE create_timestamp >= unix_timestamp('2018-01-01')
AND create_timestamp < unix_timestamp('2018-02-01')

这样,只会计算一次,然后直接去匹配索引。避免了全表扫描。

场景九:没有充分利用缓存

现象

部分对数据实时性要求不高的场景。会有相同条件的查询频繁执行的情况,甚至于并发执行多个相同查询条件的查询。这时候如果每次都查询数据库,势必造成了资源的浪费。

建议

把这部分查询结果,缓存到redis中。把大部分请求量引到redis去。

场景十:单表数据量过大

现象

由于对MYSQL依赖严重,导致很多更适合存在NOSQL数据库的数据,也被存到了MYSQL中,而且行数非常多。这样的表,无论是查询、还是更新、或是DDL操作,都需要停服之后、花大量时间去做。

建议

(1)单表不要超过1千万行,大小不要超过5G;如果超过,可以考虑分库分表;
(2)根据场景,考虑用其他数据存储工具、或其他业务上的逻辑来解决大表的问题;

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
存储 弹性计算 关系型数据库
阿里云服务器ESSD云盘性能等级PL0、PL1、PL2、PL3区别,云盘性能级别PL知识点参考
在我们选择阿里云服务器系统盘和数据盘时,如果是选择ESSD云盘,还需要选择云盘的云盘性能级别PL,PL性能级别有PL3、PL2、PL1、PL0四个性能级别的云盘规格,如果是通过阿里云的活动来购买云服务器的话,由于系统盘默认一般为20G或40G容量,可选的PL性能级别通常只有PL0(单盘IOPS性能上限1万)和PL1(单盘IOPS性能上限5万)可选择,有的用户肯能并不清楚ESSD云盘的性能等级之间有何区别,单盘IOPS性能指的是什么,本文为大家介绍一下ESSD云盘的云盘性能级别PL3、PL2、PL1、PL0相关知识点。
阿里云服务器ESSD云盘性能等级PL0、PL1、PL2、PL3区别,云盘性能级别PL知识点参考
|
26天前
|
SQL 关系型数据库 MySQL
阿里云MySQL数据库价格、购买、创建账号密码和连接数据库教程
阿里云数据库使用指南:购买MySQL、SQL Server等RDS实例,选择配置和地区,完成支付。创建数据库和账号,设置权限。通过DMS登录数据库,使用账号密码访问。同地域VPC内的ECS需将IP加入白名单以实现内网连接。参考链接提供详细步骤。
366 3
|
14天前
|
存储 关系型数据库 MySQL
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
|
14天前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
|
21天前
|
存储 关系型数据库 数据库
超1/3中国500强企业都在用的「汇联易」,为什么选用阿里云RDS?
迎峰而上:汇联易依托阿里云RDS通用云盘,加速业务智能化升级
超1/3中国500强企业都在用的「汇联易」,为什么选用阿里云RDS?
|
26天前
|
弹性计算 关系型数据库 MySQL
阿里云MySQL云数据库优惠价格、购买和使用教程分享!
阿里云数据库使用流程包括购买和管理。首先,选购支持MySQL、SQL Server、PostgreSQL等的RDS实例,如选择2核2GB的MySQL,设定地域和可用区。购买后,等待实例创建。接着,创建数据库和账号,设置DB名称、字符集及账号权限。最后,通过DMS登录数据库,填写账号和密码。若ECS在同一地域和VPC内,可内网连接,记得将ECS IP加入白名单。
419 2
|
27天前
|
SQL 关系型数据库 MySQL
阿里云mysql数据库价格购买和使用教程
阿里云数据库使用指南:购买MySQL、SQL Server等RDS实例,通过选择配置、地域和可用区完成购买。创建数据库和账号,分配权限。使用DMS登录数据库,进行管理操作。确保ECS与RDS在同一地域的VPC内,配置白名单实现内网连接。详细步骤见官方文档。
626 1
|
29天前
|
关系型数据库 MySQL 数据库
使用阿里云的数据传输服务DTS(Data Transmission Service)进行MySQL 5.6到MySQL 8.0的迁移
【2月更文挑战第29天】使用阿里云的数据传输服务DTS(Data Transmission Service)进行MySQL 5.6到MySQL 8.0的迁移
216 2
|
29天前
|
弹性计算 小程序 开发者
阿里云服务器性能测评:25M带宽阿里云云服务器支持多少人访问?
在深入探讨25M带宽云服务器的性能时,我们首先要明确一个核心概念:带宽与服务器能够支持的同时访问量之间存在着直接的关联。那么,大家可能会好奇,带宽为25M的云服务器究竟能够支持多少用户同时访问呢?
119 0
|
30天前
|
SQL 关系型数据库 MySQL
购买阿里云RDS实例
购买阿里云RDS实例
165 2