mysql從5.1版本開始支援分割區功能。MySQL5.1中分割區表示式必須是整數,或者返回整數的表示式;而MySQL5.5中提供了非整數表示式分割區的支援。MySQL資料庫的分割區是區域性分割區索引,一個分割區中既存了資料,又放了索引;也就是說,每個區的聚集索引和非聚集索引都放在各自區的(不同的物理檔案)。MySQL支援4種分割區型別:RANGE分割區,LIST分割區,HASH分割區,KEY分割區。
本教學操作環境:windows7系統、mysql8版本、Dell G3電腦。
mysql支援分割區。
MySQL在5.1時新增了對水平分割區的支援。分割區是將一個表或索引分解成多個更小,更可管理的部分。每個區都是獨立的,可以獨立處理,也可以作為一個更大物件的一部分進行處理。這個是MySQL支援的功能,業務程式碼無需改動。要知道MySQL是面向OLTP的資料,它不像TIDB等其他DB。那麼對於分割區的使用應該非常小心,如果不清楚如何使用分割區可能會對效能產生負面的影響。
MySQL資料庫的分割區是區域性分割區索引,一個分割區中既存了資料,又放了索引。也就是說,每個區的聚集索引和非聚集索引都放在各自區的(不同的物理檔案)。目前MySQL資料庫還不支援全域性分割區。
無論哪種型別的分割區,如果表中存在主鍵或唯一索引時,分割區列必須是唯一索引的一個組成部分。
分割區表的限制因素
(1)、一個表最多隻能有1024個分割區。
(2)、 MySQL5.1中,分割區表示式必須是整數,或者返回整數的表示式。在MySQL5.5中提供了非整數表示式分割區的支援。
(3)、如果分割區欄位中有主鍵或者唯一索引的列,那麼多有主鍵列和唯一索引列都必須包含進來。即:分割區欄位要麼不包含主鍵或者索引列,要麼包含全部主鍵和索引列。
(4)、分割區表中無法使用外來鍵約束。
(5)、MySQL的分割區適用於一個表的所有資料和索引,不能只對表資料分割區而不對索引分割區,也不能只對索引分割區而不對錶分割區,也不能只對表的一部分資料分割區。
目前MySQL支援一下幾種型別的分割區,RANGE分割區,LIST分割區,HASH分割區,KEY分割區。如果表存在主鍵或者唯一索引時,分割區列必須是唯一索引的一個組成部分。實戰十有八九都是用RANGE分割區。
RANGE分割區是實戰最常用的一種分割區型別,行資料基於屬於一個給定的連續區間的列值被放入分割區。但是記住,當插入的資料不在一個分割區中定義的值的時候,會拋異常。
RANGE分割區主要用於日期列的分割區,比如交易表啊,銷售表啊等。可以根據年月來存放資料。如果你分割區走的唯一索引中date型別的資料,那麼注意了,優化器只能對YEAR(),TO_DAYS(),TO_SECONDS(),UNIX_TIMESTAMP()這類函數進行優化選擇。實戰中可以用int型別,那麼只用存yyyyMM就好了。也不用關心函數了。
CREATE TABLE `m_test_db`.`Order` ( `id` INT NOT NULL AUTO_INCREMENT, `partition_key` INT NOT NULL, `amt` DECIMAL(5) NULL, PRIMARY KEY (`id` , `partition_key`) ) PARTITION BY RANGE (partition_key) PARTITIONS 5 ( PARTITION part0 VALUES LESS THAN (201901) , PARTITION part1 VALUES LESS THAN (201902) , PARTITION part2 VALUES LESS THAN (201903) , PARTITION part3 VALUES LESS THAN (201904) , PARTITION part4 VALUES LESS THAN (201905));
這時候我們先插入一些資料
INSERT INTO `m_test_db`.`Order` (`id`, `partition_key`, `amt`) VALUES ('1', '201901', '1000'); INSERT INTO `m_test_db`.`Order` (`id`, `partition_key`, `amt`) VALUES ('2', '201902', '800'); INSERT INTO `m_test_db`.`Order` (`id`, `partition_key`, `amt`) VALUES ('3', '201903', '1200');
現在我們查詢一下,通過EXPLAIN PARTITION命令發現SQL優化器只需搜對應的區,不會搜尋所有分割區
如果sql語句有問題,那麼會走所有區。會很危險。所以分割區表後,select語句必須走分割區鍵。
以下3種不是太常用,就一筆帶過了。
LIST分割區和RANGE分割區很相似,只是分割區列的值是離散的,不是連續的。LIST分割區使用VALUES IN,因為每個分割區的值是離散的,因此只能定義值。
說到雜湊,那麼目的很明顯了,將資料均勻的分佈到預先定義的各個分割區中,保證每個分割區的數量大致相同。
KEY分割區和HASH分割區相似,不同之處在於HASH分割區使用使用者定義的函數進行分割區,KEY分割區使用資料庫提供的函數進行分割區。
一項技術,不是用了就一定帶來益處。比如顯式鎖功能比內建鎖強大,你沒玩好可能導致很不好的情況。分割區也是一樣,不是啟動了分割區資料庫就會執行的更快,分割區可能會給某些sql語句效能提高,但是分割區主要用於資料庫高可用性的管理。
資料庫應用分為2類,一類是OLTP(線上事務處理),一類是OLAP(線上分析處理)。對於OLAP應用分割區的確可以很好的提高查詢效能,因為一般分析都需要返回大量的資料,如果按時間分割區,比如一個月使用者行為等資料,則只需掃描響應的分割區即可。在OLTP應用中,分割區更加要小心,通常不會獲取一張大表的10%的資料,大部分是通過索引返回幾條資料即可。
比如一張表1000w資料量,如果一句select語句走輔助索引,但是沒有走分割區鍵。那麼結果會很尷尬。如果1000w的B+樹的高度是3,現在有10個分割區。那麼不是要(3+3)*10次的邏輯IO?(3次聚集索引,3次輔助索引,10個分割區)。所以在OLTP應用中請小心使用分割區表。
在日常開發中,如果想檢視sql語句的分割區查詢結果可以使用explain partitions + select sql來獲取,partitions標識走了哪幾個分割區。
mysql> explain partitions select * from TxnList where startTime>'2016-08-25 00:00:00' and startTime<'2016-08-25 23:59:00'; +----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+ | 1 | SIMPLE | ClientActionTrack | p20160825 | ALL | NULL | NULL | NULL | NULL | 33868 | Using where | +----+-------------+-------------------+------------+------+---------------+------+---------+------+-------+-------------+ 1 row in set (0.00 sec)
注:
1.MySQL Workbench下新增分割區的截圖
2. Table has no partition for value 12
在12月的某一天,我檢視了生產的紀錄檔檔案,忽然發現系統一直在報錯:Table has no partition for value 12。仔細檢查分割區sql發現分割區的時候用的是less than
也就是說我在註釋1截圖裡面的分割區是不包括12月的區的。執行以下命令增加分割區:
ALTER TABLE table_name ADD PARTITION (PARTITION p_12 VALUES LESS THAN (13));
如果沒有進行適當的處理,將會報錯。所以在進行 RANGE 分割區時,要思考這種情況。一般情況下,就時在最後新增一個 MAXVALUE 分割區,如下:
PARTITION p_max VALUES LESS THAN MAXVALUE
【相關推薦:】
以上就是mysql是否支援分割區的詳細內容,更多請關注TW511.COM其它相關文章!