`
天梯梦
  • 浏览: 13756867 次
  • 性别: Icon_minigender_2
  • 来自: 洛杉矶
社区版块
存档分类
最新评论

mysql —— 分表分区

 
阅读更多
面对当今大数据存储,设想当mysql中一个表的总记录超过1000W,会出现性能的大幅度下降吗?
答案是肯定的,一个表的总记录超过1000W,在操作系统层面检索也是效率非常低的
 
解决方案:
目前针对海量数据的优化有两种方法:
 
1、大表拆小表的方式(主要有分表和分区两者技术)
(1)分表技术
垂直分割
1111
优势:降低高并发情况下,对于表的锁定。
不足:对于单表来说,随着数据库的记录增多,读写压力将进一步增大。
 
 
水平分割
2222
 
如果单表的IO压力大,可以考虑用水平分割,其原理就是通过hash算法,将一张表分为N多页,并通过一个新的表(总表),记录着每个页的的位置。假如一 个门户网站,它的数据库表已经达到了1000万条记录,那么此时如果通过select去查询,必定会效率低下(不做索引的前提下)。为了降低单表的读写 IO压力,通过水平分割,将这个表分成10个页,同时生成一个总表,记录各个页的信息,那么假如我查询一条id=100的记录,它不再需要全表扫描,而是 通过总表找到该记录在哪个对应的页上,然后再去相应的页做检索,这样就降低了IO压力。
 
水平分表技术就是将一个表拆成多个表,比较常见的方式就是将表中的记录按照某种HASH算法进行拆分,同时,这种分区方法也必须对前端的应用程序中的 SQL进行修改方能使用,而且对于一个SQL语句,可能会修改两个表,那么你必须要修改两个SQL语句来完成你这个逻辑的事务,会使得逻辑判断越来越复 杂,这样会增加程序的维护代价,所以我们要避免这样的情况出现。
 
2、SQL语句的优化(索引)
SQL语句优化:可以通过增加索引等来调整,但同时数据量的增大会导致索引的维护代价增大。
 
分区优点:
1、减少IO
2、提高读写
3、方便数据管理
 
分区与分表的区别:
分区是逻辑层面进行了水平分割,对于应用程序来说,它仍是一张表。
分区就是把一张表的数据分成N多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘上
 
1. 实现方式上

(1)mysql的分表是真正的分表,一张表分成很多表后,每一个小表都是完整的一张表,都对应三个文件,一个.MYD数据文件,.MYI索引文件,.frm表结构文件。

[root@BlackGhost test]# ls |grep user
alluser.MRG
alluser.frm
user1.MYD
user1.MYI
user1.frm
user2.MYD
user2.MYI
user2.frm
 

 

简单说明一下,上面的分表是利用了merge存储引擎(分表的一种),alluser是总表,下面有二个分表,user1,user2。他们二个都是独立 的表,取数据的时候,我们可以通过总表来取。这里总表是没有.MYD,.MYI这二个文件的,也就是说,总表他不是一张表,没有数据,数据都放在分表里 面。我们来看看.MRG到底是什么东西

[root@BlackGhost test]# cat alluser.MRG |more
user1
user2

#INSERT_METHOD=LAST
 

 

从上面我们可以看出,alluser.MRG里面就存了一些分表的关系,以及插入数据的方式。可以把总表理解成一个外壳,或者是连接池。
 

(2)分区不一样,一张大表进行分区后,他还是一张表,不会变成二张表,但是他存放数据的区块变多了。

[root@BlackGhost test]# ls |grep aa
aa#P#p1.MYD
aa#P#p1.MYI
aa#P#p2.MYD
aa#P#p2.MYI
aa#P#p3.MYD
aa#P#p3.MYI
aa.frm
aa.par
 

 

从上面我们可以看出,aa这张表,分为3个区。我们都知道一张表对应三个文件.MYD,.MYI,.frm。分区根据一定的规则把数据文件和索引文件进行 了分割,还多出了一个.par文件,打开.par文件后你可以看出他记录了,这张表的分区信息,跟分表中的.MRG有点像。分区后,还是一张,而不是多张 表。
 
2. 数据处理上
(1)分表后,数据都是存放在分表里,总表只是一个外壳,存取数据发生在一个一个的分表里面。看下面的例子:
 
select * from user1 user2 where id='12'表面上看,是对表alluser进行操作的,其实不是的。是对alluser里面的分表进行了操作。
 
(2)分区,不存在分表的概念,分区只不过把存放数据的文件分成了许多小块,分区后的表,还是一张表。数据处理还是由自己来完成。
select * from alluser where id='12'
 
3. 提高性能上
(1) 分表后,单表的并发能力提高了,磁盘I/O性能也提高了。因为查询一次所花的时间变短了,如果出现高并发的话,总表可以根据不同的查询,将并发压力分到不 同的小表里面。本来一个非常大的.MYD文件现在也分摊到各个小表的.MYD中去了,因此对于磁盘IO压力也降低了。
 
(2)mysql提出了分区的概念,我觉得就想突破磁盘I/O瓶颈,想提高磁盘的读写能力,来增加mysql性能。
在这一点上,分区和分表的侧重点不同,分表重点是存取数据时,如何提高mysql并发能力上;而分区呢,则是如何突破磁盘的读写能力,从而达到提高mysql性能的目的。
 
4. 实现的难易度上
(1)分表的方法有很多,用merge来分表,是最简单的一种方式。这种方式根分区难易度差不多,并且对程序代码来说可以做到透明的。如果是用其他分表方式就比分区麻烦了。
 
(2)分区实现是比较简单的,建立分区表,跟建平常的表没什么区别,并且对开代码端来说是透明的。
 
分区类型
hash、range、list、key
  • RANGE分区:基于一个给定连续区间的列值,把多行分配给分区。
  • LIST分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择。
  • HASH分区:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。这个函数可以包含MySQL 中有效的、产生非负整数值的任何表达式。

hash用在数据相对比较随机的情况下。它是根据表中的内容进行hash运算后随机平均分配,假设这个列是性别,则不适合用hash分区,因为内容要么是男,要么是女,没有随机性。

  • KEY分区:类似于按HASH分区,区别在于KEY分区只支持计算一列或多列,且MySQL 服务器提供其自身的哈希函数。必须有一列或多列包含整数值。 ----很少用到
 
如何查看数据库是否支持分区技术?
3333
 

创建分区:

mysql> create table t1(id int)partition by hash(id)partitions 3;
Query OK, 0 rows affected (0.03 sec)
 

 

【实验】
分别创建一个分区的表和非分区的表,进行性能测试
 

创建分区表

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);
Query OK, 0 rows affected (0.14 sec)
 

 

创建非分区表

mysql> create table no_part_tab ( c1 int default NULL, c2 varchar(30) default null, c3 date default null) engine=myisam;
Query OK, 0 rows affected (0.11 sec)

mysql> \d // #由于下面要用到存储过程,这里需要修改结束符为“//”。所谓的存储过程其实也就是众多sql语句的集合。
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, 0 rows affected (0.04 sec)

mysql> \d ; // 执行完这个存储过程后,需要将结束符修改回去
 

 

上面的存储过程实际上是为了创建大量的数据(800万条)

mysql> call load_part_tab(); // 调用load_part_tab这个存储过程
Query OK, 1 row affected (9 min 18.95 sec)
 

 

快速将part_tab里面的数据插入到no_part_tab里面

mysql> insert no_part_tab select * from part_tab;
Query OK, 8000000 rows affected (8.97 sec)
Records: 8000000 Duplicates: 0 Warnings: 0
 

 

测试一:

实验之前确保两个表里面的数据是一致的!保证实验的可比性

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.49 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 (3.94 sec)

mysql> desc 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.09 sec)

ERROR:
No query specified

mysql> desc select count(*) from no_part_tab where c3 > date '1995-01-01' and c3 < date '1995-12-31'\G;
*************************** 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)

ERROR:
No query specified
 

 

结论:可以看到,做了分区之后,只需要扫描79万条语句,而不做分区的,则需要进行全表扫描,故可以看出,做了分区技术后,可以提高读写效率。

测试2:
创建索引,查看语句执行情况

mysql> create index idx_c3 on no_part_tab(c3);
Query OK, 8000000 rows affected (32.68 sec)
Records: 8000000 Duplicates: 0 Warnings: 0
 

 

结果分析:

结论:为未分区的表创建了索引之后,再次执行相同的语句,可以看到该SQL语句是根据range索引进行检索,而不是全表扫描了。明显效率也提高了。

mysql> desc select count(*) from no_part_tab where c3 > date '1995-01-01' and c3 < date '1995-12-31'\G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: NO_part_tab
type: range
possible_keys: idx_c3
key: idx_c3
key_len: 4
ref: NULL
rows: 785678
Extra: Using where; Using index
1 row in set (0.16 sec)

ERROR:
No query specified

 

测试3:

测试做索引与未作索引的读写效率。

mysql> create index idx_c3 on part_tab(c3);
Query OK, 8000000 rows affected (31.85 sec)
Records: 8000000 Duplicates: 0 Warnings: 0

mysql> desc 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: index
possible_keys: idx_c3
key: idx_c3
key_len: 4
ref: NULL
rows: 798458
Extra: Using where; Using index
1 row in set (0.14 sec)

ERROR:
No query specified

 

测试未创建索引字段

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

 

结论:可以看到如果没通过索引进行检索所耗费的时间将长于通过索引进行检索。

测试4:删除

mysql> delete from part_tab where c3 > date '1995-01-01' and c3 < date '1995-12-31';
Query OK, 795181 rows affected (14.02 sec)

mysql> delete from no_part_tab where c3 > date '1995-01-01' and c3 < date '1995-12-31';
Query OK, 795181 rows affected (15.21 sec)

 

结论:可以看到,在删除方面,有分区的还是比没分区的快一点。从而体现了其便于数据管理的特点
方 便数据管理这点,我通过下面的例子来说明:比如数据库的表t1记录的是今年一整年(12个月)公司的营业额,在未分区的情况下,也就是说数据文件都存放在 同一个文件里面,那么假如现在要删除第一个季度的记录,那么需要全表扫描才能得出结果。但如果t1这个表事先做了分区,那么我只需要分别删除1,2,3这 三个文件即可。所以从一定程度上,还是方便了管理。

 

原文:http://pmghong.blog.51cto.com/3221425/1301945

转自:mysql —— 分表分区

 

 

 

分享到:
评论

相关推荐

    mysql分区资源整理

    虽然分区与水平分表(也称为分表)在目的上有相似之处——都是为了提高性能和管理大规模数据,但二者在实现机制上存在本质差异: 1. **分区是逻辑分表**:分区是在数据库底层实现的,用户看到的仍是一个单一的表,...

    DRDS分库分表—— RDS关系数据库云服务的水平扩容技术

    DRDS在实施分库分表时具有一些限制,例如目前只支持MySQL用户,并且在某些场景下需要预留主键和分区键。 未来,随着技术的发展和用户需求的增长,DRDS会持续进行技术改进和功能增强,以适应大数据时代数据处理的...

    对分库分表的一些想法

    "对分库分表的一些想法"这个主题涉及到数据库优化中的一个重要策略——数据分区。数据分区是为了提高数据库性能,解决单一表数据量过大导致的查询效率低下、写入瓶颈等问题。以下是关于分库分表的一些详细知识: ...

    mysql进阶学习一之知识点总结(csdn)————程序.pdf

    以下是对"mysql进阶学习一之知识点总结(csdn)———程序.pdf"的详细解析: 1. **MySQL安装与初始化**: - 在CentOS7环境下,通常使用`yum`命令来安装MySQL 5.7。安装过程可能会遇到问题,需要多次尝试并参考相关...

    后端开发之分库分表技术详解及其面试准备

    此外,针对引入分库分表后面临的挑战——如数据操作难题、SQL语句执行问题、跨库事务处理、全局唯一标识符生成等进行了详述。而后介绍了当前较为成熟的相关工具和技术——特别是Sharding Sphere,对其工作原理、应用...

    MySQL查询随机数据的4种方法和性能对比

    2. 分区表:如果数据量极大,可以考虑使用分区表来分割数据,使得查询更加高效。 3. 查询优化:尽量减少不必要的JOIN操作,避免全表扫描,只选取必要的列,以及合理使用WHERE条件。 4. 参数调整:根据服务器硬件...

    MySQL常用语句指令和功能详解.rar

    本资料包“MySQL常用语句指令和功能详解.rar”包含了一份关于MySQL基础操作和高级特性的详细文本文件——“MySQL常用语句指令和功能详解.txt”。下面,我们将深入探讨MySQL的一些关键知识点。 1. 数据库创建与删除...

    面试常问必备之MySQL面试55题.zip

    8. **分区与分表**:大型数据库可能需要分区或分表来提高性能。了解范围分区、列表分区、哈希分区和复合分区。 9. **备份与恢复**:熟悉mysqldump工具进行数据库备份,以及如何使用mysql命令恢复数据。 10. **性能...

    MySQL分布式数据库架构及企业实践-基于Mycat中间件

    Mycat是一款优秀的开源数据库连接池产品,它支持对MySQL进行读写分离、分库分表等操作。通过Mycat,可以方便地构建一个高性能、可扩展性强的MySQL集群。 - **读写分离**:Mycat能够自动根据SQL语句类型(读/写)将...

    MySql参考手册.zip

    这份"MySql参考手册.zip"包含的两个CHM文件——"mysql5_chs.chm"和"MySQL_chinese.chm"提供了全面的MySQL中文文档,是数据库开发者和管理员的重要参考资料。 1. **MySQL基础概念** - 数据库:存储和组织数据的系统...

    NoSQL开篇——为什么要使用NoSQL

    同时,MySQL引入了表分区和MySQL Cluster,但这些解决方案仍不足以满足互联网应用的扩展性需求。 NoSQL的优势在于其灵活性和可扩展性。与传统的关系数据库相比,NoSQL数据库更适合处理大数据、高并发和动态变化的...

    数据库 实验十三.rar

    3. 分区与分表:对于大型表,可以采用分区或分表策略提高查询性能。 六、备份与恢复 1. 数据导出:`mysqldump -u 用户名 -p 数据库名 &gt; 文件名.sql`将数据库导出为SQL脚本。 2. 数据导入:`mysql -u 用户名 -p ...

    php面试题整理.docx

    在面对大数据量时,分库分表策略能有效缓解单表压力,例如垂直分割(按字段划分)和水平分割(按数据行划分)。推荐参考链接中的内容进行深入学习。 对于MySQL的双机热备和负载均衡,这涉及到高可用性和容错性。...

    S2-2-MySchool数据库设计优化(PPT+源码)【第五章】

    5. **分区与分表策略**:对于大型数据库,分区和分表是常见的优化手段。根据时间、ID或其他关键字段进行分区,可以提高查询效率和管理便利性。 6. **数据库性能监控**:使用MySQL自带的性能监视工具,如SHOW STATUS...

    有道笔记

    此外,通过分区、分表等技术,进一步提高数据处理效率。 除了数据库层面的优化,有道笔记在工具使用上也有独到之处。工具的选择和整合能有效提升开发效率和维护质量。例如,版本控制工具Git可以帮助团队协同开发,...

    达内ttms.sql

    在实践中,"ttms.sql"可能还涉及到数据库性能优化,如使用存储过程、视图和触发器来提升效率,或者通过分区、分表等手段处理大数据量。另外,安全性也是数据库设计的重要考虑因素,例如设置访问权限、加密敏感数据等...

    计算机相关专业本科毕业论文

    3) 表结构优化,包括合理设计数据库模式,避免数据冗余,以及采用分区、分表等技术来分散负载;4) 存储优化,如选择合适的存储引擎,调整内存参数,以及使用数据压缩来节省存储空间。 论文还涉及到了数据库性能监控...

    中科大软院数据库实验一

    为了处理大量交易记录,可能会选择分区或分表策略。这部分工作直接影响到数据库的性能和可扩展性。 接下来,实验中提到的数据库导出的截图,可能是为了展示数据的存储状态,或者用于备份和迁移目的。在实际操作中,...

Global site tag (gtag.js) - Google Analytics