MySQL optimization strategy ten million large table

The amount of data: ten million

In fact, just a ten million digital senses, our impression is that the data is greater.

Here we need to refine the concept, because as the business changes and time, amount of data that will change, we should take a dynamic thinking to look at this index, so that for different scenarios that we should have handled differently strategy.

  1. The amount of data is ten million, may reach one hundred million or more

Some data is usually water logging business, which data growth over time will gradually increase, more than ten million threshold is very easy thing.

  1. The data amount to ten million, is a relatively stable

If the amount of data is relatively stable, generally biased in favor of the data in some states, such as 10 million users, then those users of information corresponding row of data records in the table have, as the business grows, the relative order of magnitude is relatively stable.

  1. The amount of data is ten million, should not have so much data

This situation is mostly found in our passive, usually found when it was too late, for example, you see a configuration table, the amount of tens of millions of data; or that some of the table data has been stored for a long time, 99% of the data fall outdated data or garbage data.

Object: Data Sheet

Data manipulation process like in the presence of a plurality of database than the pipe, these pipes are flowing data to be processed, the usefulness of these data and the home is not the same.

The data is generally divided into three service types:

  1. Data flowing
    water type data is stateless, there is no correlation between the multi-pen business, each business over time will produce new documents.
    Such as transaction flow, pay water, as long as the documents can be done to insert a new business, characterized by the following data does not depend on previous data, all data in chronological flow into the database.
  2. State Data
    status Data is stateful, multi-pen between business depends on stateful data, but also to ensure the accuracy of the data, it must get the balance of the original such as when recharging, in order to pay for success.
  3. Data configuration
    of this type of data the data amount is small, simple structure, usually static data, low frequency changes.

At this point, we can have on the overall context of an understanding, if to do optimization, in fact, to face such a 3 3 matrix, if you want to consider the ratio of read-write table (reading and writing less, read less write more ... ), it will 3 3 * 4 = 24 species apparently do exhaustive is not displayed, but also completely unnecessary, you can specify different business strategies for different data storage properties and operational characteristics.

In this regard we take the way to seize the key, put some common optimization ideas to sort it out, especially inside the core idea is to optimize the design of our entire ruler, and the difficulty we decided to do dynamic and risks of this matter.

Here Insert Picture Description

Goal: Optimization

At this stage, we are saying to optimize the program, summarize a bit more, it is relatively a whole. Whole is divided into five parts:
Here Insert Picture Description

In fact, we usually refer to the sub-library sub-table and other programs are just a small part, then if you expand on the rich.
Here Insert Picture Description

Understandably, the amount of data we have to watch is that it must support level is relatively large, DBA sure you want to maintain more than one table, how to better manage, while being able to support the expansion in business development, while ensuring performance, which is placed in front of us a few mountains.

We are speaking about these five improvements:

  • Design specifications
  • Business layer optimization
  • Architecture layer optimization
  • Database Optimization
  • Management Optimization

Design specifications

Here we first mentioned specification design, not the design on the other tall.
Here Insert Picture Description
The nature of norms is not the solution, but effective way to eliminate some of the potential problems, large table for ten million specification to follow, I brushed some of the details are as follows, and can cover some of the basic design and use our common problems.

For example, just-field table design are varchar (500), it is in fact a very irregular implementation, we have to expand the talk about these specifications.

Configuration specifications:
  • Use InnoDB storage engine MySQL database by default.

  • 保证字符集设置统一,MySQL 数据库相关系统、数据库、表的字符集都使用 UTF8,应用程序连接、展示等可以设置字符集的地方也都统一设置为 UTF8 字符集。
    注:UTF8 格式是存储不了表情类数据,需要使用 UTF8MB4,可在 MySQL 字符集里面设置。在 8.0 中已经默认为 UTF8MB4,可以根据公司的业务情况进行统一或者定制化设置。

  • MySQL 数据库的事务隔离级别默认为 RR(Repeatable-Read),建议初始化时统一设置为 RC(Read-Committed),对于 OLTP 业务更适合。

  • 数据库中的表要合理规划,控制单表数据量,对于 MySQL 数据库来说,建议单表记录数控制在 2000W 以内。

  • MySQL 实例下,数据库、表数量尽可能少;数据库一般不超过 50 个,每个数据库下,数据表数量一般不超过 500 个(包括分区表)。

建表规范:
  • InnoDB 禁止使用外键约束,可以通过程序层面保证。
  • 存储精确浮点数必须使用 DECIMAL 替代 FLOAT 和 DOUBLE。
  • 整型定义中无需定义显示宽度,比如:使用 INT,而不是 INT(4)。
  • 不建议使用 ENUM 类型,可使用 TINYINT 来代替。
  • 尽可能不使用 TEXT、BLOB 类型,如果必须使用,建议将过大字段或是不常用的描述型较大字段拆分到其他表中;另外,禁止用数据库存储图片或文件。
  • 存储年时使用 YEAR(4),不使用 YEAR(2)。
  • 建议字段定义为 NOT NULL。
  • 建议 DBA 提供 SQL 审核工具,建表规范性需要通过审核工具审核后。
命名规范:
  • 库、表、字段全部采用小写。
  • 库名、表名、字段名、索引名称均使用小写字母,并以“_”分割。
  • 库名、表名、字段名建议不超过 12 个字符。(库名、表名、字段名支持最多 64 个字符,但为了统一规范、易于辨识以及减少传输量,统一不超过 12 字符)
  • 库名、表名、字段名见名知意,不需要添加注释。
    Here Insert Picture Description
索引规范:
  • 索引建议命名规则:idx_col1_col2[_colN]、uniq_col1_col2[_colN](如果字段过长建议采用缩写)。
  • 索引中的字段数建议不超过 5 个。
  • 单张表的索引个数控制在 5 个以内。
  • InnoDB 表一般都建议有主键列,尤其在高可用集群方案中是作为必须项的。
  • 建立复合索引时,优先将选择性高的字段放在前面。
  • UPDATE、DELETE 语句需要根据 WHERE 条件添加索引。
  • 不建议使用 % 前缀模糊查询,例如 LIKE “%weibo”,无法用到索引,会导致全表扫描。
  • 合理利用覆盖索引,例如:SELECT email,uid FROM user_email WHERE uid=xx,如果 uid 不是主键,可以创建覆盖索引 idx_uid_email(uid,email)来提高查询效率。
  • 避免在索引字段上使用函数,否则会导致查询时索引失效。
  • 确认索引是否需要变更时要联系 DBA。
应用规范:
  • 避免使用存储过程、触发器、自定义函数等,容易将业务逻辑和DB耦合在一起,后期做分布式方案时会成为瓶颈。
  • 考虑使用 UNION ALL,减少使用 UNION,因为 UNION ALL 不去重,而少了排序操作,速度相对比 UNION 要快,如果没有去重的需求,优先使用 UNION ALL。
  • 考虑使用 limit N,少用 limit M,N,特别是大表或 M 比较大的时候。
  • 减少或避免排序,如:group by 语句中如果不需要排序,可以增加 order by null。
  • 统计表中记录数时使用 COUNT(),而不是 COUNT(primary_key) 和 COUNT(1)。InnoDB 表避免使用 COUNT() 操作,计数统计实时要求较强可以使用 Memcache 或者 Redis,非实时统计可以使用单独统计表,定时更新。
  • 做字段变更操作(modify column/change column)的时候必须加上原有的注释属性,否则修改后,注释会丢失。
  • 使用 prepared statement 可以提高性能并且避免 SQL 注入。
  • SQL 语句中 IN 包含的值不应过多。
  • UPDATE、DELETE 语句一定要有明确的 WHERE 条件。
  • WHERE 条件中的字段值需要符合该字段的数据类型,避免 MySQL 进行隐式类型转化。
  • SELECT、INSERT 语句必须显式的指明字段名称,禁止使用 SELECT * 或是 INSERT INTO table_name values()。
  • INSERT 语句使用 batch 提交(INSERT INTO table_name VALUES(),(),()……),values 的个数不应过多。

业务层优化

业务层优化应该是收益最高的优化方式了,而且对于业务层完全可见,主要有业务拆分,数据拆分和两类常见的优化场景(读多写少,读少写多)!
Here Insert Picture Description

业务拆分

业务拆分分为如下两个方面:

  • 将混合业务拆分为独立业务
  • 将状态和历史数据分离

业务拆分其实是把一个混合的业务剥离成为更加清晰的独立业务,这样业务 1,业务 2…独立的业务使得业务总量依旧很大,但是每个部分都是相对独立的,可靠性依然有保证。

对于状态和历史数据分离,我可以举一个例子来说明。

例如:我们有一张表 Account,假设用户余额为 100。
Here Insert Picture Description
我们需要在发生数据变更后,能够追溯数据变更的历史信息,如果对账户更新状态数据,增加 100 的余额,这样余额为 200。

这个过程可能对应一条 update 语句,一条 insert 语句。对此我们可以改造为两个不同的数据源,account 和 account_hist。

在 account_hist 中就会是两条 insert 记录,如下:
Here Insert Picture Description
而在 account 中则是一条 update 语句,如下:
Here Insert Picture Description
这也是一种很基础的冷热分离,可以大大减少维护的复杂度,提高业务响应效率。

数据拆分

按照日期拆分:这种使用方式比较普遍,尤其是按照日期维度的拆分,其实在程序层面的改动很小,但是扩展性方面的收益很大。

  • 数据按照日期维度拆分,如 test_20191021。
  • 数据按照周月为维度拆分,如 test_201910。
  • 数据按照季度,年维度拆分,如 test_2019。

采用分区模式:分区模式也是常见的使用方式,采用 hash,range 等方式会多一些。

在 MySQL 中我是不大建议使用分区表的使用方式,因为随着存储容量的增长,数据虽然做了垂直拆分,但是归根结底,数据其实难以实现水平扩展,在 MySQL 中是有更好的扩展方式。

读多写少优化场景

采用缓存,采用 Redis 技术,将读请求打在缓存层面,这样可以大大降低 MySQL 层面的热点数据查询压力。

读少写多优化场景

读少写多优化场景,可以采用三步走:

  • 采用异步提交模式,异步对于应用层来说最直观的就是性能的提升,产生最少的同步等待。
  • 使用队列技术,大量的写请求可以通过队列的方式来进行扩展,实现批量的数据写入。
  • 降低写入频率,这个比较难理解,我举个例子:
    对于业务数据,比如积分类,相比于金额来说业务优先级略低的场景,如果数据的更新过于频繁,可以适度调整数据更新的范围(比如从原来的每分钟调整为 10 分钟)来减少更新的频率。
    例如:更新状态数据,积分为 200,如下图所示:
    Here Insert Picture Description
    可以改造为,如下图所示:
    Here Insert Picture Description
    如果业务数据在短时间内更新过于频繁,比如 1 分钟更新 100 次,积分从 100 到 10000,则可以根据时间频率批量提交。

例如:更新状态数据,积分为 100,如下图所示:
Here Insert Picture Description
无需生成 100 个事务(200 条 SQL 语句)可以改造为 2 条 SQL 语句,如下图所示:
Here Insert Picture Description
对于业务指标,比如更新频率细节信息,可以根据具体业务场景来讨论决定。

架构层优化

架构层优化其实就是我们认为的那种技术含量很高的工作,我们需要根据业务场景在架构层面引入一些新的花样来。
Here Insert Picture Description

系统水平扩展场景

采用中间件技术:可以实现数据路由,水平扩展,常见的中间件有 MyCAT,ShardingSphere,ProxySQL 等。
Here Insert Picture Description
采用读写分离技术:这是针对读需求的扩展,更侧重于状态表,在允许一定延迟的情况下,可以采用多副本的模式实现读需求的水平扩展,也可以采用中间件来实现,如 MyCAT,ProxySQL,MaxScale,MySQL Router 等。

Here Insert Picture Description

采用负载均衡技术:常见的有 LVS 技术或者基于域名服务的 Consul 技术等。

兼顾 OLTP+OLAP 的业务场景

可以采用 NewSQL,优先兼容 MySQL 协议的 HTAP 技术栈,如 TiDB。

离线统计的业务场景

有几类方案可供选择:

  • 采用 NoSQL 体系,主要有两类,一类是适合兼容 MySQL 协议的数据仓库体系,常见的有 Infobright 或者 ColumnStore,另外一类是基于列式存储,属于异构方向,如 HBase 技术。
  • 采用数仓体系,基于 MPP 架构,如使用 Greenplum 统计,如 T+1 统计。

数据库优化

数据库优化,其实可打的牌也不少,但是相对来说空间没有那么大了,我们来逐个说一下。
Here Insert Picture Description

事务优化

根据业务场景选择事务模型,是否是强事务依赖。对于事务降维策略,我们来举出几个小例子来。

降维策略 1:存储过程调用转换为透明的 SQL 调用

对于新业务而言,使用存储过程显然不是一个好主意,MySQL 的存储过程和其他商业数据库相比,功能和性能都有待验证,而且在目前轻量化的业务处理中,存储过程的处理方式太“重”了。

有些应用架构看起来是按照分布式部署的,但在数据库层的调用方式是基于存储过程,因为存储过程封装了大量的逻辑,难以调试,而且移植性不高。

这样业务逻辑和性能压力都在数据库层面了,使得数据库层很容易成为瓶颈,而且难以实现真正的分布式。

所以有一个明确的改进方向就是对于存储过程的改造,把它改造为 SQL 调用的方式,可以极大地提高业务的处理效率,在数据库的接口调用上足够简单而且清晰可控。

降维策略 2:DDL 操作转换为 DML 操作

有些业务经常会有一种紧急需求,总是需要给一个表添加字段,搞得 DBA 和业务同学都挺累,可以想象一个表有上百个字段,而且基本都是 name1,name2……name100,这种设计本身就是有问题的,更不用考虑性能了。

究其原因,是因为业务的需求动态变化,比如一个游戏装备有 20 个属性,可能过了一个月之后就增加到了 40 个属性,这样一来,所有的装备都有 40 个属性,不管用没用到,而且这种方式也存在诸多的冗余。

我们在设计规范里面也提到了一些设计的基本要素,在这些基础上需要补充的是,保持有限的字段,如果要实现这些功能的扩展,其实完全可以通过配置化的方式来实现,比如把一些动态添加的字段转换为一些配置信息。

配置信息可以通过 DML 的方式进行修改和补充,对于数据入口也可以更加动态、易扩展。

降维策略 3:Delete 操作转换为高效操作

有些业务需要定期来清理一些周期性数据,比如表里的数据只保留一个月,那么超出时间范围的数据就要清理掉了。

而如果表的量级比较大的情况下,这种 Delete 操作的代价实在太高,我们可以有两类解决方案来把 Delete 操作转换为更为高效的方式。

第一种是根据业务建立周期表,比如按照月表、周表、日表等维度来设计,这样数据的清理就是一个相对可控而且高效的方式了。

第二种方案是使用 MySQL rename 的操作方式,比如一张 2 千万的大表要清理 99% 的数据,那么需要保留的 1% 的数据我们可以很快根据条件过滤补录,实现“移形换位”。

SQL 优化

其实相对来说需要的极简的设计,很多点都在规范设计里面了,如果遵守规范,八九不离十的问题都会杜绝掉。

  • SQL 语句简化,简化是 SQL 优化的一大利器,因为简单,所以优越。
  • 尽可能避免或者杜绝多表复杂关联,大表关联是大表处理的噩梦,一旦打开了这个口子,越来越多的需求需要关联,性能优化就没有回头路了,更何况大表关联是 MySQL 的弱项,尽管 Hash Join 才推出,不要像掌握了绝对大杀器一样,在商业数据库中早就存在,问题照样层出不穷。
  • SQL 中尽可能避免反连接,避免半连接,这是优化器做得薄弱的一方面,什么是反连接,半连接?
    其实比较好理解,举个例子:not in,not exists 就是反连接,in,exists 就是半连接,在千万级大表中出现这种问题,性能是几个数量级的差异。
索引优化

应该是大表优化中需要把握的一个度:

  • 首先必须有主键,规范设计中第一条就是,此处不接收反驳。
  • Second, SQL queries based on an index or a unique index that the query model as simple as possible.
  • Finally, as far as possible to eliminate the range of data queries, range scan or minimize the large table in the ten million cases.

Management Optimization

This should be part of the solution in all the most neglected part of, and I placed at the end, in this operation and maintenance also pay tribute to my colleagues, always thought a lot of this problem should be normal due diligence (scapegoat).
Here Insert Picture Description

Data ten million cleaning up a large table in general is more time-consuming, in this suggestion in the design of the need to improve the separation of hot and cold data strategy may sound a mouthful, I'll give you an example, the operation Drop large table DDL conversion reversible operation.

Drop the default action is submitted, and is not reversible, in database operations are synonymous with foot, MySQL There is no corresponding level Drop operation recovery, unless to restore the backup, but we can consider Drop operations into a kind of reversible DDL operations.

MySQL default ibd each table has a corresponding file, in fact, can be converted to a rename operation Drop operation, that is to migrate files from testdb testdb_arch below.

From the permissions for, testdb_arch service is not visible, the rename operation can smoothly achieve this delete function, if it is confirmed can be cleaned after a certain time, the data for the existing business process cleaning is not visible, as shown below:

Here Insert Picture Description

In addition, there are two additional suggestions, a large table for change, consider online change-peak hours as much as possible, such as using pt-osc tool change or maintenance period, will not repeat them.

To sum up, in fact, in one sentence: Optimizing ten million large table is based on business scenarios to cost optimization for the price, is definitely not an isolated one level of optimization.

Published 11 original articles · won praise 0 · views 10000 +

Guess you like

Origin blog.csdn.net/windforce828/article/details/104632896