详解亿级大数据表的几种建立分区表的方式

自5.1开始对分区(Partition)有支持,一张表最多1024个分区
查询分区数据:
SELECT * from table PARTITION(p0)

水平分区(根据列属性按行分)
举个简单例子:一个包含十年发票记录的表可以被分区为十个不同的分区,每个分区包含的是其中一年的记录。

垂直分区(按列分)
举个简单例子:一个包含了大text和BLOB列的表,这些text和BLOB列又不经常被访问,这时候就要把这些不经常使用的text和BLOB了划分到另一个分区,在保证它们数据相关性的同时还能提高访问速度。

=== 水平分区的几种模式:===

* Range(范围) – 这种模式允许DBA将数据划分不同范围。例如DBA可以将一个表通过年份划分成三个分区,80年代(1980‘s)的数据,90年代(1990‘s)的数据以及任何在2000年(包括2000年)后的数据。 

* Hash(哈希) – 这中模式允许DBA通过对表的一个或多个列的Hash Key进行计算,最后通过这个Hash码不同数值对应的数据区域进行分区,。例如DBA可以建立一个对表主键进行分区的表。 

* Key(键值) – 上面Hash模式的一种延伸,这里的Hash Key是MySQL系统产生的。 

* List(预定义列表) – 这种模式允许系统通过DBA定义的列表的值所对应的行数据进行分割。例如:DBA建立了一个横跨三个分区的表,分别根据2004年2005年和2006年值所对应的数据。 

* Composite(复合模式) - 很神秘吧,哈哈,其实是以上模式的组合使用而已,就不解释了。举例:在初始化已经进行了Range范围分区的表上,我们可以对其中一个分区再进行hash哈希分区。 

水平分区
[分区表和未分区表试验过程]

*创建分区表,按日期的年份拆分 

mysql> 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 (1995),
PARTITION p1 VALUES LESS THAN (1996) , PARTITION p2 VALUES LESS THAN (1997) ,
PARTITION p3 VALUES LESS THAN (1998) , PARTITION p4 VALUES LESS THAN (1999) ,
PARTITION p5 VALUES LESS THAN (2000) , PARTITION p6 VALUES LESS THAN (2001) ,
PARTITION p7 VALUES LESS THAN (2002) , PARTITION p8 VALUES LESS THAN (2003) ,
PARTITION p9 VALUES LESS THAN (2004) , PARTITION p10 VALUES LESS THAN (2010),
PARTITION p11 VALUES LESS THAN MAXVALUE ); 

注意最后一行,考虑到可能的最大值

*查看创建的情况:
mysql> show create table part_tab;
*创建未分区表
mysql> create table no_part_tab (c1 int(11) default NULL,c2 varchar(30) default NULL,c3 date default NULL) engine=myisam;

*通过存储过程灌入800万条测试数据

DELIMITER //
mysql> CREATE PROCEDURE load_part_tab()
       begin
    declare v int default 0;
    while v < 8000000
    do
        insert into part_tab
        values (v,‘testing partitions‘,adddate(‘1995-01-01‘,(rand(v)*36520) mod 3652));
         set v = v + 1;
    end while;
    end;
    //

Query OK, 1 row affected (8 min 17.75 sec)

mysql> insert into no_part_tab select * from part_tab;
Query OK, 8000000 rows affected (51.59 sec)
Records: 8000000 Duplicates: 0 Warnings: 0
* 测试SQL性能

mysql> select count(*) from part_tab where c3 > date ‘1995-01-01‘ and c3 < date ‘1995-12-31‘;

+----------+
| count(*) |
+----------+
|   795181 |
+----------+
1 row in set (0.55 sec)

mysql> select count(*) from no_part_tab where c3 > date ‘1995-01-01‘ and c3 < date ‘1995-12-31‘;

+----------+
| count(*) |
+----------+
|   795181 |
+----------+
1 row in set (4.69 sec)
结果表明分区表比未分区表的执行时间少90%。

* 通过explain语句来分析执行情况
mysql > explain select count(*) from no_part_tab where c3 > date ‘1995-01-01‘ and c3 < date ‘1995-12-31‘\G

/* 结尾的\G使得mysql的输出改为列模式 */
*************************** 1. row ***************************
           id: 1
select_type: SIMPLE
        table: no_part_tab
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 8000000
        Extra: Using where
1 row in set (0.00 sec)

mysql> explain select count(*) from part_tab where c3 > date ‘1995-01-01‘ and c3 < date ‘1995-12-31‘\G 

*************************** 1. row ***************************
           id: 1
select_type: SIMPLE
        table: part_tab
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 798458
        Extra: Using where
1 row in set (0.00 sec)
explain语句显示了SQL查询要处理的记录数目

* 试验创建索引后情况
mysql> create index idx_of_c3 on no_part_tab (c3);

Query OK, 8000000 rows affected (1 min 18.08 sec)
Records: 8000000 Duplicates: 0 Warnings: 0
mysql> create index idx_of_c3 on part_tab (c3);

Query OK, 8000000 rows affected (1 min 19.19 sec)
Records: 8000000 Duplicates: 0 Warnings: 0
创建索引后的数据库文件大小列表:
2008-05-24 09:23             8,608 no_part_tab.frm
2008-05-24 09:24       255,999,996 no_part_tab.MYD
2008-05-24 09:24        81,611,776 no_part_tab.MYI
2008-05-24 09:25                 0 part_tab#P#p0.MYD
2008-05-24 09:26             1,024 part_tab#P#p0.MYI
2008-05-24 09:26        25,550,656 part_tab#P#p1.MYD
2008-05-24 09:26         8,148,992 part_tab#P#p1.MYI
2008-05-24 09:26        25,620,192 part_tab#P#p10.MYD
2008-05-24 09:26         8,170,496 part_tab#P#p10.MYI
2008-05-24 09:25                 0 part_tab#P#p11.MYD
2008-05-24 09:26             1,024 part_tab#P#p11.MYI
2008-05-24 09:26        25,656,512 part_tab#P#p2.MYD
2008-05-24 09:26         8,181,760 part_tab#P#p2.MYI
2008-05-24 09:26        25,586,880 part_tab#P#p3.MYD
2008-05-24 09:26         8,160,256 part_tab#P#p3.MYI
2008-05-24 09:26        25,585,696 part_tab#P#p4.MYD
2008-05-24 09:26         8,159,232 part_tab#P#p4.MYI
2008-05-24 09:26        25,585,216 part_tab#P#p5.MYD
2008-05-24 09:26         8,159,232 part_tab#P#p5.MYI
2008-05-24 09:26        25,655,740 part_tab#P#p6.MYD
2008-05-24 09:26         8,181,760 part_tab#P#p6.MYI
2008-05-24 09:26        25,586,528 part_tab#P#p7.MYD
2008-05-24 09:26         8,160,256 part_tab#P#p7.MYI
2008-05-24 09:26        25,586,752 part_tab#P#p8.MYD
2008-05-24 09:26         8,160,256 part_tab#P#p8.MYI
2008-05-24 09:26        25,585,824 part_tab#P#p9.MYD
2008-05-24 09:26         8,159,232 part_tab#P#p9.MYI
2008-05-24 09:25             8,608 part_tab.frm
2008-05-24 09:25                68 part_tab.par
* 再次测试SQL性能
mysql> select count(*) from no_part_tab where c3 > date ‘1995-01-01‘ and c3 < date ‘1995-12-31‘;
+----------+
| count(*) |
+----------+
|   795181 |
+----------+
1 row in set (2.42 sec)   /* 为原来4.69 sec 的51%*/   

重启mysql ( net stop mysql, net start mysql)后,查询时间降为0.89 sec,几乎与分区表相同。
mysql> select count(*) from part_tab where c3 > date ‘1995-01-01‘ and c3 < date ‘1995-12-31‘;
+----------+
| count(*) |
+----------+
|   795181 |
+----------+
1 row in set (0.86 sec)

* 更进一步的试验
** 增加日期范围

mysql> select count(*) from no_part_tab where c3 > date ‘1995-01-01‘ and c3 < date ‘1997-12-31‘;
+----------+
| count(*) |
+----------+
| 2396524 |
+----------+
1 row in set (5.42 sec)

mysql> select count(*) from part_tab where c3 > date ‘1995-01-01‘ and c3 < date ‘1997-12-31‘;
+----------+
| count(*) |
+----------+
| 2396524 |
+----------+
1 row in set (2.63 sec)

** 增加未索引字段查询
mysql> select count(*) from part_tab where c3 > date ‘1995-01-01‘ and c3 < date
‘1996-12-31‘ and c2=‘hello‘;

+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.75 sec)
mysql> select count(*) from no_part_tab where c3 > date ‘1995-01-01‘ and c3 < date ‘1996-12-31‘ and c2=‘hello‘;

+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (11.52 sec)

删除老数据,分区表的速度更快:
MySQL [Mytestdb]> alter table part_tab  drop  PARTITION p1;
速度比delete删除快很多;

= 初步结论 =
* 分区和未分区占用文件空间大致相同 (数据和索引文件)
* 如果查询语句中有未建立索引字段,分区时间远远优于未分区时间
* 如果查询语句中字段建立了索引,分区和未分区的差别缩小,分区略优于未分区。

= 最终结论 =
* 对于大数据量,建议使用分区功能。
* 去除不必要的字段
* 根据手册, 增加myisam_max_sort_file_size 会增加分区性能

***************************************** 其他类型 *********************************************
[分区命令详解]

= 分区例子 =
* RANGE 类型
CREATE TABLE users (
       uid INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
       name VARCHAR(30) NOT NULL DEFAULT ‘‘,
       email VARCHAR(30) NOT NULL DEFAULT ‘‘
)
PARTITION BY RANGE (uid) (
       PARTITION p0 VALUES LESS THAN (3000000)
       DATA DIRECTORY = ‘/data0/data‘
       INDEX DIRECTORY = ‘/data1/idx‘,

       PARTITION p1 VALUES LESS THAN (6000000)
       DATA DIRECTORY = ‘/data2/data‘
       INDEX DIRECTORY = ‘/data3/idx‘,

       PARTITION p2 VALUES LESS THAN (9000000)
       DATA DIRECTORY = ‘/data4/data‘
       INDEX DIRECTORY = ‘/data5/idx‘,

       PARTITION p3 VALUES LESS THAN MAXVALUE     DATA DIRECTORY = ‘/data6/data‘
       INDEX DIRECTORY = ‘/data7/idx‘
);

在这里,将用户表分成4个分区,以每300万条记录为界限,每个分区都有自己独立的数据、索引文件的存放目录,与此同时,这些目录所在的物理磁盘分区可能也都是完全独立的,可以提高磁盘IO吞吐量。

原文地址:https://www.cnblogs.com/gxyandwmm/p/10256369.html

时间: 2024-08-29 12:39:19

详解亿级大数据表的几种建立分区表的方式的相关文章

Spark分区详解!DT大数据梦工厂王家林老师亲自讲解!

http://www.tudou.com/home/_79823675/playlist?qq-pf-to=pcqq.group 一.分片和分区的区别? 分片是从数据角度,分区是从计算的角度,其实都是从大的状态,split成小的. 二.spark分区理解 rdd作为一个分布式的数据集,是分布在多个worker节点上的.如下图所示,RDD1有五个分区(partition),他们分布在了四个worker nodes 上面,RDD2有三个分区,分布在了三个worker nodes上面. 三.默认分区

30个MySQL千万级大数据SQL查询优化技巧详解

本文总结了30个mysql千万级大数据SQL查询优化技巧,特别适合大数据里的MYSQL使用. 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t wher

大数据表的查询优化方案

如果有一张大表,表中的数据有几百万.几千万甚至上亿,要实现实时查询,查询的结果要在十秒钟之内出来,怎么办?如何做优化? 本人现在做的项目中,有个表的数据超过1千万行,超过3G的数据.现在需要对表中的数据进行查询统计,之前由于没做优化,导致此表的查询效率非常低下,让使用者非常苦恼,于是本人参与了此表的优化. 举个类似的例子,比如表中的结构如下,现在要统计某一天出生的人口数,或者统计某一城市的人口数,或者某一城市某一天出生的人口数. CREATE TABLE `population` ( `popu

Mysql千万级大数据查询优化经验 一点课堂(多岸学院)

提高mysql千万级大数据SQL查询优化30条经验(Mysql索引优化注意) 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=0

oracle 的一个大数据表 快速迁移到 Sqlserver2008数据库

"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> oracle 的一个大数据表 快速迁移到 Sqlserver2008数据库 - HappyBinhaer的专栏 - 博客频道 - CSDN.NET HappyBinhaer的专栏 目录视图 摘要视图 订阅 [活动]2017 CSDN博客专栏评选 &nbsp [5月书讯

Oracle大数据表的分表处理

1.首先给大数据表创建rownum序列号 --增加序列号字段 alter table TEST add xlh number; --填充序列号 update TEST set xlh = rownum; 2.通过xlh字段进行分数据到不同的表中(以建表的方式进行处理) create table hik_1001 as select clm1 as hik_clm1,clm2 as hik_clm2,clm3 as hik_clm3 from TEST where xlh>=1 and xlh <

mysql 造1亿条记录的单表--大数据表

读写文件 背景及木:现有数据1000w单表,为压力测试准备1亿条数据. 步骤: 1.将1000w条记录,除id外都导入到多个文件中: //DELIMITER DROP PROCEDURE if EXISTS createManyTable; create PROCEDURE createManyTable() BEGIN DECLARE i int; DECLARE fileName VARCHAR(30); set i=1; while i<251 DO SET fileName=CONCAT

每年为联想省去一个亿 ——Talend大数据解决方案实例

联想公司是一家价值 340 亿美金的个人技术公司和世界上最大的个人电脑供应商.一个企业组织如何构建其愿景.团队和平台以便于更了解其客户的特征是联想面临的最大问题. 2013年, 联想需要将所有数据管理从他们的外包供应商迁移出去.没有预算,没有团队, 没有平台, 联想必须从零开始. 挑战 什么特定产品具有最大的获利能力? 我们应该展示的产品的正确配置是什么? 价格促销及相应竞争是什么? 哪些客户受营销策略的影响并有可能改变他们的采购? 不同组的用户体验的区别是什么? 在他们放弃现有购物车中选定的产

MySQL中锁详解(行锁、表锁、页锁、悲观锁、乐观锁等)

原文地址:http://blog.csdn.net/mysteryhaohao/article/details/51669741 锁,在现实生活中是为我们想要隐藏于外界所使用的一种工具.在计算机中,是协调多个进程或线程并发访问某一资源的一种机制.在数据库当中,除了传统的计算资源(CPU.RAM.I/O等等)的争用之外,数据也是一种供许多用户共享访问的资源.如何保证数据并发访问的一致性.有效性,是所有数据库必须解决的一个问题,锁的冲突也是影响数据库并发访问性能的一个重要因素.从这一角度来说,锁对于