使用阿里云rds for MySQL数据库(0.6版本),某用户在线记录表6个月数据量近2000万条,近一年留存数据量达到4000万条。 查询速度极慢,每天都卡住。 严重影响生意。
问题前提:旧系统。 当时设计这个系统的人很可能还没有大学毕业。 表设计和SQL语句不仅垃圾,根本无法直视。 原来的开发人员都辞职了,我来维护了。 这就是传说中的一句话,守不住就跑,落入陷阱的就是我! ! !
我试图解决这个问题,所以我有这个日志。
计划概览
以上三种方案可以依次使用。 如果数据量小于1亿,则无需切换到noSQL。 开发成本太高。 我已经尝试了所有三个选项,并且都提出了实用的解决方案。 在这个过程中,我对那些逃跑一万次的开发者表示慰问:)
方案一详解:优化现有MySQL数据库
我通过电话和阿里云数据库老大沟通了解决方案,并向群里的老大请教。 总结如下(这些是精华):
设计数据库和创建表时考虑性能
SQL编写需要注意优化
分割
子表
分馆
1、设计数据库、创建表时要考虑性能。
MySQL数据库本身灵活性较高,导致性能不足,严重依赖开发人员能力。 也就是说,开发者的能力高,MySQL的性能就高。 这也是很多关系型数据库的通病,所以公司的DBA通常工资很高。
设计桌子时需要注意的事项。 简而言之,索引就是使用合适的数据类型,选择合适的索引。
选择适当的数据类型:
使用可以存储数据的最小数据类型,整数 < 日期、时间 < 字符、< blob
使用简单的数据类型,整数比字符处理起来更便宜,因为字符串比较更复杂。例如int类型存储时间类型,类型转换ip函数
使用合理的字段属性长度,固定长度表会更快。使用 enum、char 代替
尽可能使用 not null 来定义字段
尽可能少地使用文字。 如果一定要用,最好分表。
选择适当的索引列:
原开发者跑掉了,表已经创建了,我无法修改,所以:这个写法无法执行,放弃!
2、SQL编写需要注意优化
原开发者已离开,程序已上线。 我无法修改SQL,所以:这个写法无法执行,放弃!
3、发动机选型
目前广泛使用的有两种发动机:
该引擎是MySQL 5.1及之前版本的默认引擎。 其特点是:
MySQL 5.5之后成为默认索引。 其特点是:
一般来说,适合密集表,适合密集表。
速度可能超级快,占用的存储空间也小,但是程序需要事务支持,所以是必要的。 所以这个方案无法执行,放弃吧!
4.分区
MySQL在5.1版本中引入的分区是简单的水平分割。 用户在创建表时需要添加分区参数,这对应用程序是透明的,不需要修改代码。
对于用户来说,分区表是一个独立的逻辑表,但底层是由多个物理子表组成的。 实现分区的代码实际上是由一组底层表的对象封装的,但对于SQL层来说它是一个完整的封装底层的黑盒子。 MySQL实现分区的方式也意味着索引也是根据分区的子表来定义的,并没有全局索引。
用户的SQL语句需要针对分区表进行优化。 SQL条件必须包含分区条件的列,这样查询就可以定位在少量的分区上。 否则,将扫描所有分区。 你可以检查某个SQL语句是否会陷入为了对那些分区进行SQL优化,我测试了查询没有分区条件的列也会提高速度,所以这个措施值得一试。
分区的优点 分区的限制和缺点 分区类型
关于MySQL分区的概念请参考官方文档。 我在这里只是给你一些想法。
我首先将上网记录表RANGE按照月份划分为12个分区。 查询效率提升约6倍,但效果并不明显。 因此,我将ID改为HASH分区,并分为64个分区。 查询速度显着提高。 问题解决了!
结果如下:BY HASH(id)64
select count(*) from readroom_website; --11901336行记录
/* 受影响行数: 0 已找到记录: 1 警告: 0 持续时间 1 查询: 5.734 sec. */
select * from readroom_website where month(accesstime) =11 limit 10;
/* 受影响行数: 0 已找到记录: 10 警告: 0 持续时间 1 查询: 0.719 sec. */
5. 子表
分表就是按照上面的流程对一张大表进行优化,但是如果查询还是卡住,那么就将表切分成多个表,将一个查询切分成多个查询,然后将合并后的结果返回给用户。
表拆分分为垂直拆分和水平拆分,通常以某个字段作为拆分项。例如将id字段拆分为100张表:表名为
但是:分表需要修改源程序代码,会给开发带来大量的工作量,大大增加开发成本。 因此:只适合开发初期考虑大量数据的存在并做好分表处理,不适合应用。 上线后修改太贵了! ! ! 而且选择这个选项并不比选择我提供的第二个或第三个选项划算! 因此,不建议使用。
6. 分库
将一个数据库划分为多个数据库,建议读写分离。 真正建立单独的数据库也会带来大量的开发成本,得不偿失! 不建议。
选项2详细说明:将数据库升级为与MySQL 100%兼容的数据库
如果MySQL的性能不好,那就换吧。 为了保证源程序代码不被修改以及现有业务能够顺利迁移,需要改成100%兼容MySQL的数据库。
1. 开源选项
开源数据库会带来大量的运维成本,其工业品质还远远落后于MySQL。 有很多陷阱需要避免。 如果您的公司要求您建立自己的数据库,那么就选择此类产品。
2. 云端数据选择
官方介绍:是阿里云自研的下一代关系型分布式云原生数据库。 100%兼容MySQL,存储容量高达100T,性能高达MySQL的6倍。 它既结合了商业数据库稳定、可靠、高性能的特点,又具有开源数据库简单、可扩展、持续迭代的优点,而成本仅为商业数据库的1/10。
我激活它并测试了它。 支持免费MySQL数据迁移,无运营成本。 性能提升约10倍。 价格和rds差不多。 这是一个很好的替代解决方案!
淘宝用的可以顶住双十一,性能出色。 不过,我没能在公测中尝试,但还是值得期待的。
官方介绍:Cloud for MySQL(原名)是一款同时支持海量数据在线交易(OLTP)和在线分析(OLAP)的HTAP(/)关系型数据库。
我也测试了一下,发现是一个兼容OLAP和OLTP的解决方案,但是价格太高,高达10元每小时。 用它来存储太浪费了,适合存储和分析一起使用的业务。
官方介绍:DCDB又称TDSQL,是一款高性能分布式数据库,兼容MySQL协议和语法,支持自动水平分割——即业务显示为完整的逻辑表,但数据均匀分割分成多个分片。 ; 每个分片默认采用主备架构,提供容灾、恢复、监控、不间断扩容等一整套解决方案,适用于TB或PB级海量数据场景。
我不喜欢用腾讯的,就不多说了。 原因是出了问题找不到人,网上问题也解决不了,很头疼! 但价格便宜,适合很小的公司玩。
方案三详解:去掉MySQL,换成大数据引擎来处理数据
数据量超过1亿,我们别无选择,只能使用大数据。
1. 开源解决方案
家庭。 只需安装 hbase/hive 即可。 但运维成本较高,大多数企业无法承受。 没有十万元的投入,就没有好的产出!
2. 云解决方案
这是比较常见的,也是未来的趋势。 大数据由专业公司提供,小公司或个人购买服务。 大数据就像水/电等公共设施一样,存在于社会的各个方面。
中国最好的就是阿里云。
我选择了阿里云的合作。 使用起来超级舒服,按需付费,成本极低。
可以理解为开源的Hive,提供了SQL//ai算法/脚本/shell脚本等方法来操作数据。 数据以表格的形式展示,分布式存储,并采用定时任务和批处理的方式进行处理。 提供工作流程方法来管理您的数据处理任务和安排监控。
当然,你也可以选择阿里云hbase等其他产品。 这里主要关注的是离线处理,所以选择的基本都是图形界面操作。 我写了大约300行SQL,用不超过100块钱的成本解决了数据处理问题。