首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >用好 mysql 分区表

用好 mysql 分区表

原创
作者头像
潘昌伟
修改于 2017-09-01 02:01:24
修改于 2017-09-01 02:01:24
10.9K00
代码可运行
举报
文章被收录于专栏:潘昌伟的专栏潘昌伟的专栏
运行总次数:0
代码可运行

为了保证MySQL的性能,我们都建议mysql单表不要太大,也经常有人问我这样的问题,整体来说呢,建议是:单表小于2G,记录数小于1千万,十库百表。如果但行记录数非常小,那么记录数可以再偏大些,反之,可能记录数到百万级别就开始变慢了。

那么,业务量在增长,数据到瓶颈了怎么办呢,除了使用分布式数据库,我们也可以自行分库分表,或者利用mysql的分区功能实现。

本文主要介绍几种分区的选型建议和语法,其实影响分区性能最重要的一点还有索引的设计,非常关键,如果索引没设计好,可能分区表的性能并不理想,后续单独整理分享。

分区的优势:

1、冷热分离:表非常大且只在表的最后部分有热点数据,冷数据根据分区规则自动归档。

2、定期淘汰历史数据:按时间写入,历史数据可淘汰,可快速删除,空间可快速回收。

3、优化查询:在where字句中包含分区列时,分区可以大大提高查询效率,减少缓存开销、减少IO开销。

4、统计性能提升:在涉及sum()和count()这类聚合函数的查询时,可以在每个分区上面并行处理,最终只需要汇总所有分区得到的结果。

MySQL的分区规则:

范围 :PARTITIONED BY RANGE COLUMNS

列表 :PARTITION BY LIST COLUMNS

HASH:PARTITION BY HASH

KEY :PARTITION BY KEY

子分区:SUBPARTITION BY XXX

一、RANGE partitioning

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE members01 (
    id int(11) NOT NULL AUTO_INCREMENT,
    username VARCHAR(16) NOT NULL,
    email VARCHAR(35),
    joined DATETIME NOT NULL,
    PRIMARY KEY (id,joined),
    UNIQUE KEY `uk_username` (username,email,joined)
)
PARTITION BY RANGE( TO_DAYS(joined) ) (
    PARTITION p20170801 VALUES LESS THAN (736908),
    PARTITION p20170802 VALUES LESS THAN (736909)
);

这种是最常见的,也是我们MDB平台提供自动按天见分区的格式。一般也比较适合按天分区,或者固定范围的分区,比如时间范围,只能按照数字大小(年龄/编号)进行区间划分。

优势:

1、按分区快速淘汰历史数据

2、按分区字段的范围查询

这里不得不吐槽一下,有的人,每天把数据往一个统计表里面存,不做分区,也不做历史数据淘汰,等到了300G,甚至1T以后,数据出不来,火急火燎的跑过来问题要怎么删除历史数据,而且表连一个主键、索引都没有,我只能说删表吧哥(非常无赖)

二、LIST partitioning

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE members02 (
    id int(11) NOT NULL AUTO_INCREMENT,
    username VARCHAR(16) NOT NULL,
    email VARCHAR(35),
    joined DATETIME NOT NULL,
    PRIMARY KEY (id,joined),
    UNIQUE KEY `uk_username` (username,email,joined)
)
PARTITION BY LIST( TO_DAYS(joined) ) (
    PARTITION p20170801 VALUES IN (736905,736907),
    PARTITION p20170803 VALUES IN (736908,736909)
);

表面上看,咦?好像使用list分区的都可以使用rang分区实现呢,其实大部分场景两种分区方式都是可以实现的,线上实际只能使用list分区的场景也比较少。

连续数据更趋向于使用range分区, list分区一般比较适合离散数据的分区,同时可以将多个离散的属性归类存储,比如我需要把20170801、20170803、20170809三个时间的数据放一个分区,20170802、20170805、20170808放个分区,这种就适合使用list分区,针对自己业务特性进行离散的分区,可以非常灵活的将数据打散到不同的分区。可以看出这种分区策略就不适合where条件的范围查询,适合固定值的in条件查询。

优势:

1、灵活的离散数据分区,可自定义分区list规则。

2、 离散分区不适合where条件date>20170801 and date >20170809,适合固定分区的等值查询或in条件查询

三、HASH partitioning

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE members03 (
    id int(11) NOT NULL AUTO_INCREMENT,
    username VARCHAR(16) NOT NULL,
    email VARCHAR(35),
    joined DATETIME NOT NULL,
    PRIMARY KEY (id,joined),
    UNIQUE KEY `uk_username` (username,email,joined)
)
PARTITION BY hash(TO_DAYS(joined)) 
PARTITIONS 2;

hash分区很好理解,就是对指定列做hash,均匀的存到指定的分区,比如按用户名hash分区,那么按用户名进行查找的速度就会快很多,这种针对分区列数据不固定,想把数据根据分区列离散的存储到固定分区数的表中,不需要做数据淘汰的场景比较适合。

优势:

1、维护简单,分区数固定,根据hash自动分区。

2、适合固定条件的等值查询

3、对于分区列数据不固定,分区列值不固定(不适合list),可根据hash值均匀打散数据到不同分区。

四、KEY partitioning

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE members04 (
id int(11) NOT NULL AUTO_INCREMENT,
    username VARCHAR(16) NOT NULL,
    email VARCHAR(35),
    joined DATETIME NOT NULL,
    PRIMARY KEY (id,joined),
    UNIQUE KEY `uk_username` (username,email,joined)
)
PARTITION BY key(joined) 
PARTITIONS 4;

同样,使用key分区跟hash分区有着神奇的相似,不同的是,如果表有主键或者唯一键的时候无需指定key的列名,key分区自动根据键值进行分区。

优势:

对于有主键的表,可无需关心分区列,MySQL自行根据主键/唯一键分区。如果主键设置不合理,查询条件都不带主键,查询性能会很差。

五、删除分区

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
移除分区:ALTER TABLE tablename REMOVE PARTITIONING ; 
删除分区:ALTER TABLE tablename DROP PARTITIONING ;

移除分区仅仅修改表分区定义,数据不会被删除;删除分区会删除分区定义同时删除分区上的数据。

更多分区管理:(增删修改)

https://dev.mysql.com/doc/refman/5.7/en/partitioning-management.html

分区表sql操作优化器如何选择:

https://dev.mysql.com/doc/refman/5.7/en/partitioning-pruning.html

分区类型定义说明:

https://dev.mysql.com/doc/refman/5.7/en/partitioning-types.html

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
三十二、分区表
分区表就是按照某种规则将同一张表的数据分段划分到多个存储位置。对数据的分区存储提高了数据库的性能,被分去存储的数据在物理上是多个文件,但在逻辑上仍然是一个表,对表的任何操作都和没有分区之前一样。在执行增删改查等操作时,数据库会自动通过找到对应的分区,然后执行操作。
喵叔
2021/06/29
6520
Mysql性能优化四:分库,分区,分表,你们如何做?
分库分区分表概念 分区 就是把一张表的数据分成N个区块,在逻辑上看最终只是一张表,但底层是由N个物理区块组成的 。 分表 就是把一张数据量很大的表按一定的规则分解成N个具有独立存储空间的实体表。系统读写时需要根据定义好的规则得到对应的字表明,然后操作它。表名可以按照某种业务hash进行映射。 分库 一旦分表,一个库中的表会越来越多。 下面来具体看看 分区 mysql数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面(可以通过my.cnf中的datadir来查看),一张表主要对应着三
友儿
2022/09/09
1.2K0
腾讯TDSQL分区表介绍(2/2)
二级分区的情况,相比一级分区复杂一些。下面我们来看下不同的组合情况。(其中,一级hash的情况是比较特殊的,我们先来看下)
胖五斤
2022/11/10
2.6K0
MySQL · 最佳实践 · 分区表基本类型
随着MySQL越来越流行,Mysql里面的保存的数据也越来越大。在日常的工作中,我们经常遇到一张表里面保存了上亿甚至过十亿的记录。这些表里面保存了大量的历史记录。对于这些历史数据的清理是一个非常头疼事情,由于所有的数据都一个普通的表里。所以只能是启用一个或多个带where条件的delete语句去删除(一般where条件是时间)。这对数据库的造成了很大压力。即使我们把这些删除了,但底层的数据文件并没有变小。面对这类问题,最有效的方法就是在使用分区表。最常见的分区方法就是按照时间进行分区。分区一个最大的优点就是可以非常高效的进行历史数据的清理。
码农编程进阶笔记
2021/07/20
9310
MySQL分区表最佳实践
分区是一种表的设计模式,通俗地讲表分区是将一大表,根据条件分割成若干个小表。但是对于应用程序来讲,分区的表和没有分区的表是一样的。换句话来讲,分区对于应用是透明的,只是数据库对于数据的重新整理。本篇文章给大家带来的内容是关于MySQL中分区表的介绍及使用场景,有需要的朋友可以参考一下,希望对你有所帮助。
MySQL技术
2020/06/04
3.2K0
程序员必须掌握的MySQL优化指南(下)
接上篇,上篇主要是从字段类型,索引,SQL语句,参数配置,缓存等介绍了关于MySQL的优化,下面从表的设计,分库,分片,中间件,NoSQL等提供更多关于MySQL的优化。
终码一生
2022/04/14
6060
程序员必须掌握的MySQL优化指南(下)
如何优雅地优化MySQL大表
除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑、部署、运维的各种复杂度,一般以整型值为主的表在千万级以下,字符串为主的表在五百万以下是没有太大问题的。而事实上很多时候MySQL单表的性能依然有不少优化空间,甚至能正常支撑千万级以上的数据量。
Bug开发工程师
2018/07/23
1.5K0
如何优雅地优化MySQL大表
腾讯TDSQL分区表介绍(1/2)
TDSQL集群支持创建集中式实例和分布式实例。在使用分布式实例的时候,可以创建以下几种类型的表:
胖五斤
2022/11/10
3.8K0
最佳实践 · MySQL 分区表实战指南
在数据量急剧增长的今天,传统的数据库管理方式可能无法有效处理海量数据的存储和查询需求。MySQL 提供了分区表功能,这不仅能够帮助优化性能,还能简化数据管理过程。分区表允许将数据表拆分成多个逻辑上的分区,每个分区可以在物理上存储于不同的存储介质上,从而提升查询效率和数据处理速度。本文将深入探讨 MySQL 中四种主要的分区类型——范围分区(RANGE)、列表分区(LIST)、哈希分区(HASH)以及键分区(KEY),并通过实际的案例分析和示例数据,帮助你掌握如何使用这些分区技术来优化数据库性能,提升数据处理能力。
不惑
2024/09/09
9440
最佳实践 · MySQL 分区表实战指南
MySQL分区表
在最近的项目中,我们需要保存大量的数据,而且这些数据是有有效期的,为了提供查询效率以及快速删除过期数据,我们选择了MySQL的分区机制。把数据按照时间进行分区。 分区类型 ---- Range分区:最为常用,基于属于一个给定连续区间的列值,把多行分配给分区。最常见的是基于时间字段. 基于分区的列最好是整型,如果日期型的可以使用函数转换为整型。 List分区:LIST分区和RANGE分区类似,区别在于LIST是枚举值列表的集合,RANGE是连续的区间值的集合。 Hash分区:基于给定的分区个数,将
十毛
2019/04/01
5.5K0
MySQL分区表
经验分享|MySQL分区实战(RANGE)
在 MySQL 中, InnoDB存储引擎长期以来一直支持表空间的概念。在 MySQL 8.0 中,同一个分区表的所有分区必须使用相同的存储引擎。但是,也可以为同一 MySQL 服务器甚至同一数据库中的不同分区表使用不同的存储引擎。
六月暴雪飞梨花
2023/11/30
7580
经验分享|MySQL分区实战(RANGE)
Mysql调优之分区表
表非常大以至于无法全部都放在内存中,或者只在表的最后部分有热点数据,其他均是历史数据,分区表是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分。从逻辑上看,只有一张表,但是底层却是由多个物理分区组成。
iginkgo18
2022/01/13
1.8K0
mysql分区语句
要是分区数比现有的分区数多的话,只能使用 ADD来添加分区数.下面就表示增加了6个分区数
全栈程序员站长
2022/08/11
13.4K0
浅谈mysql分区、分表、分库
mysql支持的分区类型包括Range、List、Hash、Key,其中Range比较常用:
黄啊码
2021/09/26
1.8K0
mysql5.7 分区表_mysql分区表学习
Cannot delete or update a parent row: aforeign key constraint fails
全栈程序员站长
2022/08/26
4.2K0
MySQL分区表姿势
分区的功能不是在存储引擎层实现的。因此不只是InnoDB才支持分区。MyISAM、NDB都支持分区操作。
保持热爱奔赴山海
2019/09/17
6.2K0
mysql 分区键_mysql分区
就访问数据库的应用而言,逻辑上只有一个表或一个索引,但是实际上这个表可能由数10个物理分区对象组成,每个分区都是一个独立的对象,可以独自处理,可以作为表的一部分进行处理。
全栈程序员站长
2022/08/10
4.7K0
mysql 获取分区的最大值_MySQL分区表测试「建议收藏」
mysql> Create table engine1(id int) engine=innodb partition by range(id)(partition po values less than(10));
全栈程序员站长
2022/09/05
3.4K0
postgres分区表
postgres分区表是数据层层面的, 相对于普通表在内部实现复杂,但是用户无感知.
eeaters
2024/11/01
3880
postgres分区表
别看不起分区表:我要为你点个赞
接下来分别尝试有分片键查询,二级索引(idx_name)查询,无分片键查询这三种非常典型查询,并查看执行计划(并且为了防止查询结果被缓存,每条SQL都加上SQL_NO_CACHE):
程序猿DD
2019/03/08
4510
别看不起分区表:我要为你点个赞
相关推荐
三十二、分区表
更多 >
领券
一站式MCP教程库,解锁AI应用新玩法
涵盖代码开发、场景应用、自动测试全流程,助你从零构建专属AI助手
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档