為了保證mysql的效能,我們都建議mysql單錶不要太大,也經常有人問我這樣的問題,整體來說呢,建議是:單錶小於2g,記錄數小於1千萬,十庫百錶。如果但行記錄數非常小,那麼記錄數可以再偏大些,反之,可能記錄數到百萬級別就開始變慢了。
那麼,業務量在增長,資料到瓶頸了怎麼辦呢,除了使用分布式資料庫,我們也可以自行分庫分表,或者利用mysql的分割槽功能實現。
本文主要介紹幾種分割槽的選型建議和語法,其實影響分割槽效能最重要的一點還有索引的設計,非常關鍵,如果索引沒設計好,可能分割槽表的效能並不理想,後續單獨整理分享。
1、冷熱分離:表非常大且只在表的最後部分有熱點資料,冷資料根據分割槽規則自動歸檔。
2、定期淘汰歷史資料:按時間寫入,歷史資料可淘汰,可快速刪除,空間可快速**。
3、優化查詢:在where字句中包含分割槽列時,分割槽可以大大提高查詢效率,減少快取開銷、減少io開銷。
4、統計效能提公升:在涉及sum()和count()這類聚合函式的查詢時,可以在每個分割槽上面並行處理,最終只需要彙總所有分割槽得到的結果。
mysql的分割槽規則:
範圍 :partitioned by range columns
列表 :partition by list columns
hash:partition by hash
key :partition by key
子分割槽:subpartition by ***
create table members01 (這種是最常見的,也是我們mdb平台提供自動按天見分割槽的格式。一般也比較適合按天分割槽,或者固定範圍的分割槽,比如時間範圍,只能按照數字大小(年齡/編號)進行區間劃分。id int(11) not null auto_increment,
username varchar(16) not null,
email varchar(35),
joined datetime not null,
primary key (id,joined),
unique key `uk_username` (username,email,joined)
)partition by range( to_days(joined) ) (
partition p20170801 values less than (736908),
partition p20170802 values less than (736909)
);
1、按分割槽快速淘汰歷史資料
2、按分割槽欄位的範圍查詢
這裡不得不吐槽一下,有的人,每天把資料往乙個統計表裡面存,不做分割槽,也不做歷史資料淘汰,等到了300g,甚至1t以後,資料出不來,火急火燎的跑過來問題要怎麼刪除歷史資料,而且錶連乙個主鍵、索引都沒有,我只能說刪表吧哥(非常無賴)
create table members02 (表面上看,咦?好像使用list分割槽的都可以使用rang分割槽實現呢,其實大部分場景兩種分割槽方式都是可以實現的,線上實際只能使用list分割槽的場景也比較少。id int(11) not null auto_increment,
username varchar(16) not null,
email varchar(35),
joined datetime not null,
primary key (id,joined),
unique key `uk_username` (username,email,joined)
)partition by list( to_days(joined) ) (
partition p20170801 values in (736905,736907),
partition p20170803 values in (736908,736909)
);
連續資料更趨向於使用range分割槽, list分割槽一般比較適合離散資料的分割槽,同時可以將多個離散的屬性歸類儲存,比如我需要把20170801、20170803、20170809三個時間的資料放乙個分割槽,20170802、20170805、20170808放個分割槽,這種就適合使用list分割槽,針對自己業務特性進行離散的分割槽,可以非常靈活的將資料打散到不同的分割槽。可以看出這種分割槽策略就不適合where條件的範圍查詢,適合固定值的in條件查詢。
1、靈活的離散資料分割槽,可自定義分割槽list規則。
2、 離散分割槽不適合where條件date>20170801 and date >20170809,適合固定分割槽的等值查詢或in條件查詢
hash分割槽很好理解,就是對指定列做hash,均勻的存到指定的分割槽,比如按使用者名稱hash分割槽,那麼按使用者名稱進行查詢的速度就會快很多,這種針對分割槽列資料不固定,想把資料根據分割槽列離散的儲存到固定分割槽數的表中,不需要做資料淘汰的場景比較適合。
優勢:
1、維護簡單,分割槽數固定,根據hash自動分割槽。
2、適合固定條件的等值查詢
3、對於分割槽列資料不固定,分割槽列值不固定(不適合list),可根據hash值均勻打散資料到不同分割槽。
create table members04 (同樣,使用key分割槽跟hash分割槽有著神奇的相似,不同的是,如果表有主鍵或者唯一鍵的時候無需指定key的列名,key分割槽自動根據鍵值進行分割槽。id int(11) not null auto_increment,
username varchar(16) not null,
email varchar(35),
joined datetime not null,
primary key (id,joined),
unique key `uk_username` (username,email,joined)
)partition by key(joined)
partitions 4;
優勢:
對於有主鍵的表,可無需關心分割槽列,mysql自行根據主鍵/唯一鍵分割槽。如果主鍵設定不合理,查詢條件都不帶主鍵,查詢效能會很差。
移除分割槽:alter table tablename remove partitioning ;移除分割槽僅僅修改表分割槽定義,資料不會被刪除;刪除分割槽會刪除分割槽定義同時刪除分割槽上的資料。刪除分割槽:alter table tablename drop partitioning ;
分割槽表sql操作優化器如何選擇:
分割槽型別定義說明:
MySQL分割槽表
分割槽表是一種粗粒度,簡易的索引策略,適用於大資料的過濾場景.最適合的場景是,沒有合適的索引時,對其中幾個分割槽表進行全表掃瞄.或者只有乙個分割槽表和索引是熱點,而且這個分割槽和索引能夠全部儲存在記憶體中.限制單錶分割槽數不要超過150個,並且注意某些導致無法做分割槽過濾的細節,分割槽表對於單條記錄...
mysql分割槽表
對使用者來說,分割槽表是乙個獨立的邏輯表,但是底層由多個物理子表組成。實現分割槽的 實際上是對一組底層表的控制代碼物件的封裝。mysql在建立表時使用partition by子句定義每個分割槽存放的資料。在執行查詢的時候,優化器會根據分割槽定義過濾那些沒有我們需要資料的分割槽,這樣查詢就無須掃瞄所有...
mysql分割槽表 MySQL分割槽表的正確使用方法
mysql分割槽表概述 我們經常遇到一張表裡面儲存了上億甚至過十億的記錄,這些表裡面儲存了大量的歷史記錄。對於這些歷史資料的清理是乙個非常頭疼事情,由於所有的資料都乙個普通的表裡。所以只能是啟用乙個或多個帶where條件的delete語句去刪除 一般where條件是時間 這對資料庫的造成了很大壓力。...