首页 > 代码库 > MySQL 表分区详解

MySQL 表分区详解

一、什么是表分区
通俗地讲表分区是将一大表,根据条件分割成若干个小表。mysql5.1开始支持数据表分区了。
如:某用户表的记录超过了1000万条,那么就可以根据入库日期将表分区,也可以根据所在地将表分区。当然也可根据其他的条件分区。

二、为什么要对表进行分区
为了改善大型表以及具有各种访问模式的表的可伸缩性,可管理性和提高数据库效率。
分区的一些优点包括:
      1)、与单个磁盘或文件系统分区相比,可以存储更多的数据。
      2)、对于那些已经失去保存意义的数据,通常可以通过删除与那些数据有关的分区,很容易地删除那些数据。相反地,在某些情况下,添加新数据的过程又可以通过为那些新数据专门增加一个新的分区,来很方便地实现。通常和分区有关的其他优点包括下面列出的这些。MySQL分区中的这些功能目前还没有实现,但是在我们的优先级列表中,具有高的优先级;我们希望在5.1的生产版本中,能包括这些功能。
      3)、一些查询可以得到极大的优化,这主要是借助于满足一个给定WHERE语句的数据可以只保存在一个或多个分区内,这样在查找时就不用查找其他剩余的分区。因为分区可以在创建了分区表后进行修改,所以在第一次配置分区方案时还不曾这么做时,可以重新组织数据,来提高那些常用查询的效率。
      4)、涉及到例如SUM()和COUNT()这样聚合函数的查询,可以很容易地进行并行处理。这种查询的一个简单例子如 “SELECT salesperson_id, COUNT (orders) as order_total FROM sales GROUP BY salesperson_id;”。通过“并行”,这意味着该查询可以在每个分区上同时进行,最终结果只需通过总计所有分区得到的结果。
      5)、通过跨多个磁盘来分散数据查询,来获得更大的查询吞吐量。

三、分区类型
 
· RANGE分区:基于属于一个给定连续区间的列值,把多行分配给分区。 
· LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。 
· HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。
· KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL 服务器提供其自身的哈希函数。必须有一列或多列包含整数值。

1.RANGE分区

基于属于一个给定连续区间的列值,把多行分配给分区。这些区间要连续且不能相互重叠,使用VALUES LESS THAN操作符来进行定义。以下是实例。

2.LIST分区

类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。
      LIST分区通过使用“PARTITION BY LIST(expr)”来实现,其中“expr” 是某列值或一个基于某个列值、并返回一个整数值的表达式,然后通过“VALUES IN (value_list)”的方式来定义每个分区,其中“value_list”是一个通过逗号分隔的整数列表。

3.HASH分区      

 基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。
      要使用HASH分区来分割一个表,要在CREATE TABLE 语句上添加一个“PARTITION BY HASH (expr)”子句,其中“expr”是一个返回一个整数的表达式。它可以仅仅是字段类型为MySQL 整型的一列的名字。此外,你很可能需要在后面再添加一个“PARTITIONS num”子句,其中num 是一个非负的整数,它表示表将要被分割成分区的数量。

4.KSY分区

类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL 服务器提供其自身的哈希函数。必须有一列或多列包含整数值。

不同的表分区对比如下

技术分享

 

下面来操作MySQL表分实例操作

  注意为了查看方便我这边对mysql操作都是用客户端工具Navicat For Mysql 进行连接操作。

 1.创建分区表,按日期和年份拆分 使用的是 myisam 引擎

-- 创建表分区,按日期的年份拆分
create table part_tab(c1 int default null,c2 varchar(30) default null,c3 date default null) engine=myisam
PARTITION by range(year(c3))(
PARTITION p0 values less than(2007),
PARTITION p1 values less than(2008),
PARTITION p2 values less than(2009),
PARTITION p3 values less than(2010),
PARTITION p4 values less than(2011),
PARTITION p5 values less than(2012),
PARTITION p6 values less than(2013),
PARTITION p7 values less than(2014),
PARTITION p8 values less than(2015),
PARTITION p9 values less than(2016),
PARTITION p10 values less than MAXVALUE);
-- 最后一行 ,考虑可能 最大值 默认分区

2.创建未分区表,主要用于作对比表字段和结构和分区表一模一样。

create table no_part_tab(c1 int default null,c2 varchar(30) default null,c3 date default null) engine=myisam;

3.创建测试数据这里使用存储过程快速创建100万行数据测试数据越多越方便查看,这里只测试100万行根据个人需求插入,因只是用日期分区,其他列不住细节深究。只关注日期列。

create PROCEDURE load_part_tab()
	begin 
	declare i int default 0;
  while i<1000000
  do 
   insert into part_tab values(i,‘test data part‘,
   adddate(‘2007-01-01‘,(rand(i)*36520) mod 3652));
  set i=i+1;
  end while;
  end;

4.执行存储过程插入数据

call load_part_tab();

5.进入查看我们刚才的分区表,数据库安装都是常规的路径,测试数据名称为test

[root@localhost /]# cd usr/local/mysql/data/test
[root@localhost test]# ls

技术分享

显示如上信息说明已经创建完成。

 

6.复制数据到未分区表no_part_tab

insert into no_part_tab select *from part_tab;

7.测试SQL 的性能分别查询1年的数据。

 7.1)分区表的性能

技术分享

 

7.2)未分区表的性能

技术分享

 

 查询时间非常明显的区别,注意数据量越大越明显。

 

  

MySQL 表分区详解