單張表超過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
基於給定連續的區間的值對行進行分區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 );
可能遇到的錯誤
這裏的提示已經很明確了,分區的列必須是個主鍵列
因此咱們給salary添加主鍵
查看如今數據庫文件
[root@localhost smudge]# cd /usr/local/mysql/var
插入數據測試
能夠插入更多的數據 觀察 分區文件的大小
使用 watch -n1 ls -lh 每秒監測文件大小的變化
分區語句
以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) )
表文件
經常使用於對主鍵的快速分區
分區語句
以主鍵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;
表文件
建表分區
和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;
表文件
Innodb表默認是共享存儲空間
默認my.cnf文件
默認狀況下Innodb是使用的共享表空間
當在庫smudge中, 新建一張Innodb引擎的shop表
cd usr/local/mysql/var/smudge
只有一個文件 shop.frm
shop表的索引和數據都存在ibdata1文件中
共享存儲空間的Innodb不能夠分區!
因此咱們要將Innodb表設置成獨立表空間
索引和數據都存放在ibd文件中
設置成獨立表空間
添加一行 innodb_file_per_table
service mysql restart 重啓mysql服務
添加表分區
alter table shop partition by hash(id) partitions 4 ;
查看錶文件
可見分區成功啦~~~~