Mysql 架构及优化之-表分区

写在前面

单张表超过1000W行已经算做是大数据存储场景
常规海量数据优化:大表拆小表、sql语句优化
今天咱们重点介绍大表拆小表的优化mysql

拆表方式

  • 水平拆表算法

将表user中的1000w行数据拆成user1表和user2表,每张表500w行数据
可是这样作法就是致使sql语句须要更改成 select user1,user2 ...
拆的越多,sql语句越长,因此不推荐此法拆表sql

  • 垂直分表数据库

如将user表100个字段拆成表user_base(30字段)、表user_extend(20字段)less

sql语句优化成 ... user_base left join user_extend on user_base.id = user_extend.id..测试

  • 表分区大数据

对行水平进行分表,物理存储上分区存储,每一个分表有独立的文件,应用程序上仍是一张表
Range(范围)–这种模式容许将数据划分不一样范围。例如能够将一个表经过年份划分红若干个分区。优化

Hash(哈希)–这中模式容许经过对表的一个或多个列的Hash Key进行计算,最后经过这个Hash码不一样数值对应的
数据区域进行分区。例如能够创建一个对表主键进行分区的表。
Key(键值)-上面Hash模式的一种延伸,这里的Hash Key是MySQL系统产生的。
List(预约义列表)–这种模式容许系统经过预约义的列表的值来对数据进行分割。spa

基于range分区

基于给定连续的区间的值对行进行分区rest

  • 新建表user 基于salary区间进行表分区

以字段salary为准 按照区间 [0,1000] [1000,3000] [3000,..] 将表分三个区

CREATE TABLE `user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(50) DEFAULT NULL,
      `salary` int(11) unsigned DEFAULT NULL,
      PRIMARY KEY (`id`,`salary`), #若是不给salary加主键会报错
      KEY `index_name` (`name`) USING BTREE
    )partition by range(salary)(
     partition s1000 values less than (1000),  #小于1000一张表
     partition s2000 values less than (3000),  #大于1000小于3000一张表
     partition s3000 values less than maxvalue #大于3000一张表
    );

对已有的表建立分区

alter table user partition by range(salary)(
     partition s1000 values less than (1000),  
     partition s2000 values less than (3000),   
     partition s3000 values less than maxvalue  
    );
  • 可能遇到的错误

clipboard.png

这里的提示已经很明确了,分区的列必须是个主键列

因此咱们给salary添加主键

  • 查看如今数据库文件

[root@localhost smudge]# cd /usr/local/mysql/var

clipboard.png

  • 插入数据测试

clipboard.png
clipboard.png

能够插入更多的数据 观察 分区文件的大小
使用 watch -n1 ls -lh 每秒监测文件大小的变化

clipboard.png

基于list分区

  • 分区语句

以area_id列为准, 按照华南和华北 将表分红两个区

create table shop(name varchar(50),area_id int)
        engine=myisam default charset=utf8
         partition by list(area_id)(
         partition pnorth values in (1,3,5),
         partition psouth values in (20,36,55)
   )
  • 表文件

clipboard.png

基于hash分区

经常使用于对主键的快速分区

  • 分区语句

以主键id为准,hash算法将表平均分红4个区

create table student (
      id int(11) not null auto_increment,
      name varchar(50) default null,
      age int(11) default null,
      primary key (id)
     ) engine=myisam default charset=utf8
     partition by hash(id) partitions 4;
  • 表文件

clipboard.png

基于key分区

  • 建表分区

和hash分区相似将表分红4个区

create table teacher (
      id int(11) not null auto_increment,
      name varchar(50) default null,
      age int(11) default null,
      primary key (id)
    ) engine=myisam default charset=utf8
     partition by key(id) partitions 4;
  • 添加分区

alter table teacher partition by key(id) partitions 4;
  • 表文件

clipboard.png

对于Innodb引擎表的分区

  • Innodb表默认是共享存储空间

默认my.cnf文件

clipboard.png

默认状况下Innodb是使用的共享表空间

当在库smudge中, 新建一张Innodb引擎的shop表

cd usr/local/mysql/var/smudge

clipboard.png

只有一个文件 shop.frm

clipboard.png

shop表的索引和数据都存在ibdata1文件中

共享存储空间的Innodb不能够分区!

因此咱们要将Innodb表设置成独立表空间
索引和数据都存放在ibd文件中

  • 设置成独立表空间

添加一行 innodb_file_per_table

clipboard.png

service mysql restart 重启mysql服务

  • 添加表分区

alter table shop partition by hash(id) partitions 4 ;
  • 查看表文件

clipboard.png

可见分区成功啦~~~~

相关文章
相关标签/搜索