MySQL大數據的優化以及分解存儲mysql
前言:在上一章介紹了MySQL的優化以及優化的思路,那麼若是有一種狀況若是數據庫已經創建好了索引,在使用sql語句索引查詢時;可是在慢查詢日誌當中任然找到了以前的sql語句會有哪幾種狀況:算法
1):sql語句的索引沒有起到效果,sql
2):查詢的數據量過大,形成數據的查詢緩慢,數據庫
在工做當中每一個數據庫都會存在龐大的數據量,好比說訪問量等等都會形成數據的查詢緩慢,那麼如何解決這個問題,接下來往下看:app
分區和分表:less
咱們的數據庫數據愈來愈大,隨之而來的是單個表中數據太多。以致於查詢書讀變慢,並且因爲表的鎖機制致使應用操做也搜到嚴重影響,出現了數據庫性能瓶頸。ide
1、分表性能
什麼是分表?大數據
分表是將一個大表按照必定的規則分解成多張具備獨立存儲空間的實體表,每一個表都對應三個文件,MYD數據文件,.MYI索引文件,.frm表結構文件。這些表能夠分佈在同一塊磁盤上,也能夠在不一樣的機器上。app讀寫的時候根據事先定義好的規則獲得對應的表名,而後去操做它。主要針對myisam存儲,若是是innodb存儲那麼將會是.idb文件和.frm文件優化
將單個數據庫表進行拆分,拆分紅多個數據表,而後用戶訪問的時候,根據必定的算法(如用hash的方式,也能夠用求餘(取模)的方式),讓用戶訪問不一樣的表,這樣數據分散到多個數據表中,減小了單個數據表的訪問壓力。提高了數據庫訪問性能。分表的目的就在於此,減少數據庫的負擔,縮短查詢時間。
注:客戶端訪問的時候根本不知道表已經被分開了,任然屬於一個邏輯的總體對於客戶端來講,客戶端主要關心的是查詢的內容以及查詢的速度效率,可是做爲一名DBA必需要了解這些;只有這樣纔可以知足客戶的要求。
另外在分表的時候分爲兩種;垂直分割和水平分割:
垂直切分是指數據表列的拆分,把一張列比較多的表拆分爲多張表
水平拆分是指數據錶行的拆分,把一張的表的數據拆成多張表來存放。
分表的方式:
1)mysql集羣
它並非分表,但起到了和分表相同的做用。集羣可分擔數據庫的操做次數,將任務分擔到多臺數據庫上。集羣能夠讀寫分離,減小讀寫壓力。從而提高數據庫性能。
2)預先估計會出現大數據量而且訪問頻繁的表,將其分爲若干個表
好比說娛樂新聞的app能夠經過每一分鐘的訪問量,推算出每一個小時,以及每一天的大概訪問狀況,若是是這樣的話,那麼咱們就以分表存儲這些數據,例如建立10000張表,設定好閾值,當必定的數據量達到預先設定的值得時候就想下一個表當中存儲內容,保證數據庫的性能。
3)利用merge存儲引擎來實現分表
對於DBA來講,若是要把已有的大數據量表分開比較痛苦,最痛苦的事就是改代碼,由於程序裏面的sql語句已經寫好了,用merge存儲引擎來實現分表, 這種方法比較適合。
那麼咱們來介紹下merge的用法以及功能:
merge存儲引擎:
merge分表,分爲主表和子表,主表相似於一個殼子,邏輯上封裝了子表,實際上數據都是存儲在子表中的。
注:字表是用來存放真實數據的地方是不能在進行細分的,可是能夠合併,若是要建立多個字表,就在開始建立的時候多建立幾個,進行估算大概須要幾個。
咱們能夠經過主表插入和查詢數據,若是清楚分表規律,也能夠直接操做子表。
那麼咱們來對merge進行一個演示,但願你們對merge有一個更加深入的瞭解
建立一個完整表存儲着全部的成員信息(表名爲tty)
mysql> drop database IF EXISTS test; =======>若是test存在那麼就刪掉它
mysql> create database test;=========>建立test數據庫
mysql> use test; ==========>進入test庫
create table tty( ==============>建立tty表
id bigint auto_increment primary key, ============> 將id號設置爲主鍵
name varchar(20), =============>name的字符類型
sextinyint not nulldefault '0' ==========>性別的字符類型
)engine=myisam default charset=utf8 auto_increment=1; ===========> 存儲引擎爲myisam,utf-8字符集,能夠自動擴展。
接下來往裏面添加點數據:
mysql> insert into tty(name,sex) values('tom1',1);
mysql> insert into tty(name,sex) select name,sex from tty;
第二條語句多執行幾回就有了不少數據
執行以後咱們來查詢一下有多少條數據:
mysql> select * from tty; {有8192條數據}
下面咱們進行分表,這裏咱們把tty分兩個表tb_tty1,tb_tty2。
建立tb_tty1表:
mysql> use test;
DROP table IF EXISTS tb_tty1;
create table tb_tty1(
id bigint primary key ,
name varchar(20),
sex tinyint not null default '0'
)ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
DROP table IF EXISTS tb_tty2;
create table tb_tty2(
id bigint primary key,
name varchar(20),
sex tinyint not null default '0'
)ENGINE=MyISAM DEFAULT CHARSET=utf8;
建立tb_tty2表
//建立tb_tty2也能夠用下面的語句 create table tb_tty2 like tb_tty1;
建立主表tb_tty
注:INSERT_METHOD,此參數INSERT_METHOD = NO 表示該表不能作任何寫入操做只做爲查詢使用,INSERT_METHOD = LAST表示插入到最後的一張表裏面。INSERT_METHOD = first表示插入到第一張表裏面。
查看一下tb_tty表、tb_tty1、tb_tty2的結構:
mysql>desc tb_tty;
接下來,咱們把數據分到兩個分表中去:
mysql> insert into tb_tty1(id,name,sex) select id,name,sex from tty where id%2=0;
mysql> insert into tb_tty2(id,name,sex) select id,name,sex from tty where id%2=1;
若是要是分爲三個表的狀況可使用ID%3=0、ID%3=1、id%=2
查看兩個子表的數據:{前面說過共有8192條數據}
注意:總表只是一個外殼,存取數據發生在一個一個的子表裏面。
注意:每一個子表都有自已獨立的相關表文件,而主表只是一個殼,並無完整的相關表文件
2、分區
什麼是分區?
分區和分表類似,都是按照規則分解表。不一樣在於分表將大表分解爲若干個獨立的實體表,而分區是將數據分段劃分在多個位置存放,分區後,表仍是一張表,但數據散列到多個位置。
另外分區也能夠分爲兩種:
垂直分區和水平分區
水平分區(Horizontal Partitioning)這種形式分區是對錶的行進行分區,全部在表中定義的列在每一個數據集中都能找到,因此表的特性依然得以保持。
垂直分區(Vertical Partitioning)這種分區方式通常來講是經過對錶的垂直劃分來減小目標表的寬度,使某些特定的列被劃分到特定的分區,每一個分區都包含了其中的列所對應的行。
查看當將配置是否支持分區:
mysql> show plugins;
在顯示結果中,能夠看到partition是ACTIVE的,表示支持分區
以前演示了一個分表的方式,接下來爲你們演示一個分區的方式:
mysql> create database test2;
mysql> use test2;
mysql> create table if not exists user (
id int not null auto_increment,
name varchar(30) not null default ' ',
sex int(1) not null default '0',
primary key(id)
)default charset=utf8 auto_increment=1
partition by range(id) (
partition p0 values less than (3),
partition p1 values less than (6),
partition p2 values less than (9),
partition p3 values less than (12),
partition p4 values less than maxvalue
);
插入些數據
mysql> insert into test2.user(name,sex)values ('tom1','0');
mysql> insert into test2.user(name,sex)values ('tom2','1');
mysql> insert into test2.user(name,sex)values ('tom3','1');
mysql> insert into test2.user(name,sex)values ('tom4','0');
mysql> insert into test2.user(name,sex)values ('tom5','0');
mysql> insert into test2.user(name,sex)values ('tom6','1');
mysql> insert into test2.user(name,sex)values ('tom7','1');
mysql> insert into test2.user(name,sex)values ('tom8','1');
mysql> insert into test2.user(name,sex)values ('tom9','1');
mysql> insert into test2.user(name,sex)values ('tom10','1');
mysql> insert into test2.user(name,sex)values ('tom11','1');
mysql> insert into test2.user(name,sex)values ('tom12','1');
mysql> insert into test2.user(name,sex)values ('tom13','1');
mysql> insert into test2.user(name,sex)values ('tom14','1');
到存放數據庫表文件的地方看一下
經過命令:
mysql> select count(id) as count from user;
從information_schema系統庫中的partitions表中查看分區信息
從某個分區中查詢數據
mysql> select * from test2.user partition(p0);
新增分區
mysql> alter table test2.user add partition (partition partionname values less than (n));
使用此命令的時候須要的將p5刪掉以後才能夠進行新的增長
分區的合併
下面的SQL,將p1 – p3合併爲2個分區p01– p02
mysql> alter table test2.user
-> reorganize partition p1,p2,p3 into
-> (partition p01 values less than (8),
->partition p02 values less than (12)
-> );
後續爲你們繼續講解有關於mysql大數據的分解存儲方式以及思路,若是有不全的地方能夠評論。。