MySQL分区表最佳实践
前言:
分区是一种表的设计模式,通俗地讲表分区是将一大表,根据条件分割成若干个小表。但是对于应用程序来讲,分区的表和没有分区的表是一样的。换句话来讲,分区对于应用是透明的,只是数据库对于数据的重新整理。本篇文章给大家带来的内容是关于MySQL中分区表的介绍及使用场景,有需要的朋友可以参考一下,希望对你有所帮助。
1.分区的目的及分区类型
MySQL在创建表的时候可以通过使用PARTITION BY
子句定义每个分区存放的数据。在执行查询的时候,优化器根据分区定义过滤那些没有我们需要的数据的分区,这样查询就可以无需扫描所有分区,只需要查找包含需要数据的分区即可。
分区的另一个目的是将数据按照一个较粗的粒度分别存放在不同的表中。这样做可以将相关的数据存放在一起,另外,当我们想要一次批量删除整个分区的数据也会变得很方便。
下面简单介绍下四种常见的分区类型:
- RANGE分区:最为常用,基于属于一个给定连续区间的列值,把多行分配给分区。最常见的是基于时间字段。
- LIST分区:LIST分区和RANGE分区类似,区别在于LIST是枚举值列表的集合,RANGE是连续的区间值的集合。
- HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL中有效的、产生非负整数值的任何表达式。
- KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL服务器提供其自身的哈希函数。必须有一列或多列包含整数值。
上述四种分区类型中,RANGE分区
即范围分区是最常用的。RANGE分区的特点是多个分区的范围要连续,但是不能重叠,默认情况下使用VALUES LESS THAN属性,即每个分区不包括指定的那个值。
2.分区操作示例
本节内容以RANGE分区为例,介绍下分区表相关的操作。
# 创建分区表
mysql> CREATE TABLE `tr` (
-> `id` INT,
-> `name` VARCHAR(50),
-> `purchased` DATE
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8
-> PARTITION BY RANGE( YEAR(purchased) ) (
-> PARTITION p0 VALUES LESS THAN (1990),
-> PARTITION p1 VALUES LESS THAN (1995),
-> PARTITION p2 VALUES LESS THAN (2000),
-> PARTITION p3 VALUES LESS THAN (2005),
-> PARTITION p4 VALUES LESS THAN (2010),
-> PARTITION p5 VALUES LESS THAN (2015)
-> );
Query OK, 0 rows affected (0.28 sec)
# 插入数据
mysql> INSERT INTO `tr` VALUES
-> (1, 'desk organiser', '2003-10-15'),
-> (2, 'alarm clock', '1997-11-05'),
-> (3, 'chair', '2009-03-10'),
-> (4, 'bookcase', '1989-01-10'),
-> (5, 'exercise bike', '2014-05-09'),
-> (6, 'sofa', '1987-06-05'),
-> (7, 'espresso maker', '2011-11-22'),
-> (8, 'aquarium', '1992-08-04'),
-> (9, 'study desk', '2006-09-16'),
-> (10, 'lava lamp', '1998-12-25');
Query OK, 10 rows affected (0.03 sec)
Records: 10 Duplicates: 0 Warnings: 0
创建后可以看到,每个分区都会对应1个ibd文件。上面创建语句还是很好理解的,在此分区表中,通过YEAR函数取出DATE日期中的年份并转化为整型,年份小于1990的存储在分区p0中,小于1995的存储在分区p1中,以此类推。请注意,每个分区的定义顺序是从最低到最高。为了防止插入的数据因找不到相应分区而报错,我们应该及时创建新的分区。下面继续展示关于分区维护的其他操作。
# 查看某个分区的数据
mysql> SELECT * FROM tr PARTITION (p2);
+------+-------------+------------+
| id | name | purchased |
+------+-------------+------------+
| 2 | alarm clock | 1997-11-05 |
| 10 | lava lamp | 1998-12-25 |
+------+-------------+------------+
2 rows in set (0.00 sec)
# 增加分区
mysql> alter table tr add partition(
-> PARTITION p6 VALUES LESS THAN (2020)
-> );
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0
# 拆分分区
mysql> alter table tr reorganize partition p5 into(
-> partition s0 values less than(2012),
-> partition s1 values less than(2015)
-> );
Query OK, 0 rows affected (0.26 sec)
Records: 0 Duplicates: 0 Warnings: 0
# 合并分区
mysql> alter table tr reorganize partition s0,s1 into (
-> partition p5 values less than (2015)
-> );
Query OK, 0 rows affected (0.12 sec)
Records: 0 Duplicates: 0 Warnings: 0
# 清空某分区的数据
mysql> alter table tr truncate partition p0;
Query OK, 0 rows affected (0.11 sec)
# 删除分区
mysql> alter table tr drop partition p1;
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0
# 交换分区
# 先创建与分区表同样结构的交换表
mysql> CREATE TABLE `tr_archive` (
-> `id` INT,
-> `name` VARCHAR(50),
-> `purchased` DATE
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.28 sec)
# 执行exchange交换分区
mysql> alter table tr exchange PARTITION p2 with table tr_archive;
Query OK, 0 rows affected (0.13 sec)
3.分区注意事项及适用场景
其实分区表的使用有很多限制和需要注意的事项,参考官方文档,简要总结几点如下:
- 分区字段必须是整数类型或解析为整数的表达式。
- 分区字段建议设置为NOT NULL,若某行数据分区字段为null,在RANGE分区中,该行数据会划分到最小的分区里。
- MySQL分区中如果存在主键或唯一键,则分区列必须包含在其中。
- Innodb分区表不支持外键。
- 更改sql_mode模式可能影响分区表的表现。
- 分区表不影响自增列。
从上面的介绍中可以看出,分区表适用于一些日志记录表。这类表的特点是数据量大、并且有冷热数据区分,可以按照时间维度来进行数据归档。这类表是比较适合使用分区表的,因为分区表可以对单独的分区进行维护,对于数据归档更方便。
4.分区表为什么不常用
在我们项目开发中,分区表其实是很少用的,下面简单说明下几点原因:
- 分区字段的选择有限制。
- 若查询不走分区键,则可能会扫描所有分区,效率不会提升。
- 若数据分布不均,分区大小差别较大,可能性能提升也有限。
- 普通表改造成分区表比较繁琐。
- 需要持续对分区进行维护,比如到了6月份前就要新增6月份的分区。
- 增加学习成本,存在未知风险。
总结:
本文较为详细的介绍了MySQL分区相关内容,如果想使用分区表的话,建议提早做好规划,在初始化的时候即创建分区表并制定维护计划,使用得当还是比较方便的,特别是有历史数据归档需求的表,使用分区表会使归档更方便。当然,关于分区表的内容还有很多,有兴趣的同学可以找找官方文档,官方文档中有大量示例。
参考:
MySQL分区表最佳实践的更多相关文章
- mysql索引最佳实践
索引最佳实践使用的表CREATE TABLE `employees` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(24) NOT ...
- Mysql索引最佳实践笔记0524
#mysql5.7 innodb默认存储引擎 一.关于索引二.最佳实践三.避坑实践 一.关于索引 1.索引的作用 -提高查询效率 -数据分组.排序 -避免回表查询 -优化聚集查询 -用于多表join关 ...
- [译] MYSQL索引最佳实践
近日整理文档时发现多年前的这个文档还是蛮实用的,然后在网络搜索了一下并没有相关的译文,所以决定把它翻译过来,如有不当的地方请多包涵和指正.原文地址:https://www.percona.com/fi ...
- MySQL 索引最佳实践
原文请关注 这里 这是 文章 的翻译,在翻译过程中,会对其中涉及到的语句加上一些个人理解以及 SQL 语句的执行,并进行特别的标注. 1. 你做了一个很棒的选择,因为: 对于普通开发者和 DBA,理解 ...
- mysql 查询最佳实践
(1)负向条件查询不能使用索引 select * from order where status!=0 and stauts!=1 not in/not exists都不是好习惯 (2)前导模糊查询不 ...
- MySQL · 最佳实践 · 分区表基本类型
MySQL · 最佳实践 · 分区表基本类型 MySQL分区表概述 随着MySQL越来越流行,Mysql里面的保存的数据也越来越大.在日常的工作中,我们经常遇到一张表里面保存了上亿甚至过十亿的记录.这 ...
- MySQL · 答疑解惑 · MySQL 锁问题最佳实践
http://mysql.taobao.org/monthly/2016/03/10/ 前言 最近一段时间处理了较多锁的问题,包括锁等待导致业务连接堆积或超时,死锁导致业务失败等,这类问题对业务可能会 ...
- MySQL 性能优化 30个数据库设计的最佳实践
数据库设计是整个程序的重点之一,为了支持相关程序运行,最佳的数据库设计往往不可能一蹴而就,只能反复探寻并逐步求精,这是一个复杂的过程,也是规划和结构化数据库中的数据对象以及这些数据对象之间关系的过程. ...
- 【MySQL】锁问题最佳实践
最近一段时间处理了较多锁的问题,包括锁等待导致业务连接堆积或超时,死锁导致业务失败等,这类问题对业务可能会造成严重的影响,没有处理经验的用户往往无从下手.下面将从整个数据库设计,开发,运维阶段介绍如何 ...
随机推荐
- P1579_哥德巴赫猜想(JAVA语言)
题目背景 1742年6月7日哥德巴赫写信给当时的大数学家欧拉,正式提出了以下的猜想:任何一个大于9的奇数都可以表示成3个质数之和.质数是指除了1和本身之外没有其他约数的数,如2和11都是质数,而6不是 ...
- 【原创】Linux虚拟化KVM-Qemu分析(十一)之virtqueue
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...
- SQL注入靶场实战-小白入门
目录 SQL注入 数字型 1.测试有无测试点 2.order by 语句判断字段长,查出字段为3 3.猜出字段位(必须与内部字段数一致)(用union联合查询查看回显点为2,3) 4.猜数据库名,用户 ...
- 日志文件删除shell脚本
大日志文件切割shell脚本 #!/bin/bash # --------------------------------------------------------------------- # ...
- Fundamentals of Power Electronics 目录
Fundamentals of Power Electronics Translated By Siwei Yang (前六章翻译自Edition 2,后面部分翻译自Edition 3) Part I ...
- java面试-生产环境出现CPU占用过高,谈谈你的分析思路和定位
思路:结合Linux和JDK命令一起分析 1.用top命令找出CPU占比最高的进程 2.ps -ef|grep java|grep -v grep 或者jps -l进一步定位,得知是怎样一个后台程序惹 ...
- Dynamics CRM制作报表的时候让用户可以用自己的权限浏览数据
我们做SSRS报表的时候最头疼的问题就是用Sql查出来的数据都是全部数据没有做权限过滤,导致不同用户看到的数据是一样的. 确实Dynamics CRM产品的数据库时有对这个做处理的,其中每个实体都会有 ...
- 如何在 NET 程序万种死法中有效的生成 Dump (上)
一:背景 相信很多人都知道通过 任务管理器 抓取dump,虽然简单粗暴,但无法满足程序的无数种死法,比如: 内存膨胀,程序爆炸 CPU爆高,程序累死 应用无响应,用户气死 意外退出,和人生一样 既然手 ...
- OO第四单元&课程总结
一.本单元架构设计 第一次作业 本次作业要求解析UML类图. 首先,将UML中的各个元素(比如UmlClass.UmlInterface等)转化成自己定义的类(MyClass.MyInterface) ...
- (十六)Struts2的标签库
一.简介 Struts2的标签库使用OGNL为基础,大大简化了数据的输出,也提供了大量标签来生成页面效果,功能非常强大. 在早期的web应用开发中,jsp页面主要使用jsp脚本来控制输出.jsp页面嵌 ...