mysql 社区版 innodb_MySQL 表分区详解MyiSam引擎和InnoDb 区别(实测)

MySQL 表分区详解MyiSam引擎和InnoDb 区别(实测)

/ --------------------         写在最前面            --------------------------------/

如果表分区使用的是:innodb数据库引擎,要把分区技术做成功必须设置表为独立表空间

具体参考:https://www.jb51.net/article/134901.htm,或下面

/ --------------------         写在最前面  --     end            --------------------------------/

一、什么是表分区

通俗地讲表分区是将一大表,根据条件分割成若干个小表。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 服务器提供其自身的哈希函数。必须有一列或多列包含整数值。

不同的表分区对比如下:

dd939dd791e6b231832b0c96f0a98ced.png

下面来操作MySQL表分实例操作主要讲解 Range分区技术

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

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

create table part_tab(c1int default null,c2 varchar(30)default null,c3 datedefault null) engine=myisam

PARTITIONby 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.创建未分区表,主要用于作对比表字段和结构和分区表一模一样。

1

create table no_part_tab(c1int default null,c2 varchar(30)default null,c3 datedefault null) engine=myisam;

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

1

2

3

4

5

6

7

8

9

10

create PROCEDURE load_part_tab()

begin

declare iint default 0;

while i<1000000

do

insertinto part_tab values(i,'test data part',

adddate('2007-01-01',(rand(i)*36520) mod 3652));

set i=i+1;

endwhile;

end;

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

1

call load_part_tab();

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

1

2

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

[root@localhost test]# ls

846977736109365a99c191aa32915663.png

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

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

1

insertinto no_part_tabselect *from part_tab;

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

7.1)分区表的性能

219e6830a9b0dee859e0dae69ccdef45.png

7.2)未分区表的性能

4eb3e3382e44dd0c85aeedc2094d8bbc.png

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

8.为何会分区会有如此大的区别我们通过查询计划分析。

8.1)分区的查询计划影响的行数是:99813

fbf534dc05711b14cab04442cbf3c2e1.png

8.2)未分区查询计划影响的行数是:1000000

ab79d4b2301d3fcc61f6d1d6e88d2184.png

很明显查询条件的数据是在p1分区 所以查询的只会查询这分区,查询效果就显而易见。

9.增加未索引字段查询

1

select *from part_tabwhere c3>date'2007-01-01' and c3

查看执行时间2.55s

1

select *from no_part_tabwhere c3>date'2007-01-01' and c3

查看执行时间11.16s

对比时间差距还是很大的具体查询时间根据个人计算机性能已经数据大小进行测试,数据量越大越明显。

四.innodb表分区

在innodb数据库引擎中要把分区技术做成功必须设置表为独立表空间特别注意这点。

1.什么是共享表空间和独立表空间

贡献表空间已经独立表空间都是针对数据的存储方式而言的。

贡献表空间:某一个数据库的所有的表数据,索引文件全部放在一个文件中,默认这个共享表空间的文件路径在data目录下。默认的文件名为ibdata1初始大小为10M。

独占表空间:每个表都将会生成意独立文件方式来进行存储,每个表都有一个.frm表描述,还有一个.dbd文件.其中这个文件包括了单独一个表数据内容以及索引内容,默认情况下它的存储位置也是在表的位置之中。

2.共享表空间:

优点:

可以放表空间分成多文件存放各个磁盘上(表空间文件大小不受表大小的限制,如一个表可以分布在不同的文件上)。

数据和文件放一起方便管理。

缺点:

所有的数据和索引存放到一个文件中讲有一个很大的文件,虽然可以把一个大文件分成多个小文件,但是多个表及索引在表空间中混合存储,这样对于一个表做了大量删除操作后表空间中将会有大量的空隙,特别是对于统计分析,日志系统这类应用最不合适用共享表空间。

3.实际操作

开启innodb数据库引擎独立表空间。

编辑my.cnf 增加innodb_file_per_table=1

1

[root@localhost test]# vi /etc/my.cnf

4d5784147205bb08f01487cafcf4ae35.png

只有设置了innodb 引擎的独立表空间才能做成功表分区,特别注意。【win下无需设置】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyISAM InnoDB 区别 InnoDBMyISAM是许多人在使用MySQL时最常用的两个类型,这两个类型各有优劣,视具体应用而定。基本的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的强调的是性能,其执行数度比InnoDB类型更快,   MyISAMInnoDB 讲解   InnoDBMyISAM是许多人在使用MySQL时最常用的两个类型,这两个类型各有优劣,视具体应用而定。基本的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持已经外部键等高级数据库功能。   以下是一些细节和具体实现的差别:   ◆1.InnoDB不支持FULLTEXT类型的索引。   ◆2.InnoDB 中不保存的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count(*)语句包含 where条件时,两种的操作是一样的。   ◆3.对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM中,可以和其他字段一起建立联合索引。   ◆4.DELETE FROM table时,InnoDB不会重新建立,而是一行一行的删除。   ◆5.LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB改成MyISAM,导入数据后再改成InnoDB,但是对于使用的额外的InnoDB特性(例如外键)的不适用。   另外,InnoDB的行锁也不是绝对的,假如在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB同样会锁全,例如update table set num=1 where name like “%aaa%”   两种类型最主要的差别就是Innodb 支持事务处理与外键和行级锁.而MyISAM不支持.所以MyISAM往往就容易被人认为只适合在小项目中使用。   我作为使用MySQL的用户角度出发,InnodbMyISAM都是比较喜欢的,但是从我目前运维的数据库平台要达到需求:99.9%的稳定性,方便的扩展性和高可用性来说的话,MyISAM绝对是我的首选。   原因如下:   1、首先我目前平台上承载的大部分项目是读多写少的项目,而MyISAM的读性能是比Innodb强不少的。   2、MyISAM的索引和数据是分开的,并且索引是有压缩的,内存使用率就对应提高了不少。能加载更多索引,而Innodb是索引和数据是紧密捆绑的,没有使用压缩从而会造成InnodbMyISAM体积庞大不小。   3、从平台角度来说,经常隔1,2个月就会发生应用开发人员不小心update一个where写的范围不对,导致这个没法正常用了,这个时候MyISAM的优越性就体现出来了,随便从当天拷贝的压缩包取出对应的文件,随便放到一个数据库目录下,然后dump成sql再导回到主库,并把对应的binlog补上。如果是Innodb,恐怕不可能有这么快速度,别和我说让Innodb定期用导出xxx.sql机制备份,因为我平台上最小的一个数据库实例的数据量基本都是几十G大小。   4、从我接触的应用逻辑来说,select count(*) 和order by 是最频繁的,大概能占了整个sql总语句的60%以上的操作,而这种操作Innodb其实也是会锁的,很多人以为Innodb是行级锁,那个只是where对它主键是有效,非主键的都会锁全的。   5、还有就是经常有很多应用部门需要我给他们定期某些的数据,MyISAM的话很方便,只要发给他们对应那的frm.MYD,MYI的文件,让他们自己在对应本的数据库启动就行,而Innodb就需要导出xxx.sql了,因为光给别人文件,受字典数据文件的影响,对方是无法使用的。   6、如果和MyISAM比insert写操作的话,Innodb还达不到MyISAM的写性能,如果是针对基于索引的update操作,虽然MyISAM可能会逊色Innodb,但是那么高并发的写,从库能否追的上也是一个问题,还不如通过多实例分库分架构来解决。   7、如果是用MyISAM的话,merge引擎可以大大加快应用部门的开发速度,他们只要对这个merge做一些select count(*)操作,非常适合大项目总量约几亿的rows某一类型(如日志,调查统计)的业务。   当然Innodb也不是绝对不用,用事务的项目如模拟炒股项目,我就是用Innodb的,活跃用户20多万时候,也是很轻松应付了,因此我个人也是很喜欢Innodb的,只是如果从数据库平台应用出发,我还是会首选MyISAM。   另外,可能有人会说你MyISAM无法抗太多写操作,但是我可以通过架构来弥补,说个我现有用的数据库平台容量:主从数据总量在几百T以上,每天十多亿 pv的动态页面,还有几个大项目是通过数据接口方式调用未算进pv总数,(其中包括一个大项目因为初期memcached没部署,导致单台数据库每天处理 9千万的查询)。而我的整体数据库服务器平均负载都在0.5-1左右。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值