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

可見分區成功啦~~~~

相關文章
相關標籤/搜索