前言
本文的原文連接是: https://blog.csdn.net/freewebsys/article/details/84839478
未經博主允許不得轉載。
博主地址是:http://blog.csdn.net/freewebsys
1,關於分區
也就是說,對於原表分區后,對於應用層來說可以不做變化,我們無需改變原有的SQL語句,相當於MySQL幫我們實現了傳統分表后的SQL中間件,當然,MySQL的分區表的實現要復雜很多。
另外,在創建分區時可以指定分區的索引文件和數據文件的存儲位置,所以可以把數據表的數據分布在不同的物理設備上,從而高效地利用多個硬件設備。
一些限制:
1.在5.6.7之前的版本,一個表最多有1024個分區;從5.6.7開始,一個表最多可以有8192個分區。
2.分區表中無法使用外鍵約束。
3.主表的所有唯一索引列(包括主鍵)都必須包含分區字段。MySQL官方文檔中寫的是:
All columns used in the partitioning expression for a partitioned
table must be part of every unique key that the table may have.
https://dev.mysql.com/doc/refman/5.7/en/partitioning-limitations-partitioning-keys-unique-keys.html
https://dev.mysql.com/doc/refman/8.0/en/partitioning-management-exchange.html
別人的測試文章:
https://www.cnblogs.com/acpp/archive/2010/08/09/1795464.html
2,使用
一般情況按季度進行分區,要小於季度最后一天。
所以小於下個月的第一天。
這個時間要是沒有寫對,會報錯誤:
value must be strictly increasing for each partition
CREATE TABLE `user_part` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT ,
`name` VARCHAR(200) COMMENT '名稱',
`create_date` date NOT NULL COMMENT '日期',
PRIMARY KEY (`id`,`create_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY RANGE(TO_DAYS(`create_date`))
(
PARTITION p2018q4 VALUES LESS THAN (TO_DAYS('2019-01-01')),
PARTITION p2019q1 VALUES LESS THAN (TO_DAYS('2019-04-01')),
PARTITION p2019q2 VALUES LESS THAN (TO_DAYS('2019-07-01')),
PARTITION p2019q3 VALUES LESS THAN (TO_DAYS('2019-10-01')),
PARTITION p2019q4 VALUES LESS THAN (TO_DAYS('2020-01-01')),
PARTITION p2020q1 VALUES LESS THAN (TO_DAYS('2020-04-01')),
PARTITION p2020q2 VALUES LESS THAN (TO_DAYS('2020-07-01')),
PARTITION p2020q3 VALUES LESS THAN (TO_DAYS('2020-10-01')),
PARTITION p2020q4 VALUES LESS THAN (TO_DAYS('2021-01-01')),
PARTITION p2021q1 VALUES LESS THAN (TO_DAYS('2021-04-01')),
PARTITION p2021q2 VALUES LESS THAN (TO_DAYS('2021-07-01')),
PARTITION p2021q3 VALUES LESS THAN (TO_DAYS('2021-10-01')),
PARTITION p2021q4 VALUES LESS THAN (TO_DAYS('2022-01-01')),
PARTITION p2022q1 VALUES LESS THAN (TO_DAYS('2022-04-01')),
PARTITION p2022q2 VALUES LESS THAN (TO_DAYS('2022-07-01')),
PARTITION p2022q3 VALUES LESS THAN (TO_DAYS('2022-10-01')),
PARTITION p2022q4 VALUES LESS THAN (TO_DAYS('2023-01-01')),
PARTITION p2023q1 VALUES LESS THAN (TO_DAYS('2023-04-01')),
PARTITION p2023q2 VALUES LESS THAN (TO_DAYS('2023-07-01')),
PARTITION p2023q3 VALUES LESS THAN (TO_DAYS('2023-10-01')),
PARTITION p2023q4 VALUES LESS THAN (TO_DAYS('2024-01-01'))
);
INSERT INTO user_part VALUES
(1, 'desk organiser', '2018-10-15'),
(2, 'CD player', '2019-01-05'),
(3, 'TV set', '2019-03-10'),
(4, 'bookcase', '2019-04-10'),
(5, 'exercise bike', '2019-05-09'),
(6, 'sofa', '2019-06-05'),
(7, 'popcorn maker', '2018-01-22'),
(8, 'aquarium', '2023-08-04'),
(9, 'study desk', '2022-09-16'),
(10, 'lava lamp', '2021-12-25');
explain partitions select * from user_part where create_date = '2022-09-16';
SELECT DISTINCT PARTITION_EXPRESSION
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME='user_part';
SELECT PARTITION_NAME, TABLE_ROWS
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 'user_part' ;
通過explain語句來分析執行情況,比較下性能
分區表執行掃描了2行,數據量大的話執行時間也少很多。
而普通表則掃描了10行
3,總結
mysql 分區還是非常不錯的數據方法。
當然以后可以使用tidb 存儲數據,處理數據。
本文的原文連接是:
https://blog.csdn.net/freewebsys/article/details/84839478
博主地址是:http://blog.csdn.net/freewebsys
mysql 分區所使用的sql
查詢分區內全部數據
select * from url_8 partition(p0);//5.5.41不支持對指定分區的查詢
(今天寫一個數據遷移腳本,需要對表按分區查詢,在執行select * from xxx partition (p_xxx)的時候報錯。
后來發現是使用的版本5.5.41不支持對指定分區的查詢。在5.6增強了分區表的分區的相關操作。其中包括支持了對指定分區的查詢。
具體增強的其他特性,可以查看官方文檔)
對以存在的表進行分區
ALTER TABLE url_8 PARTITION by HASH(YEAR(`day`)) PARTITIONS 12;
刪除表的分區
ALTER TABLE url_8 REMOVE PARTITIONING;
刪除表單個分區內的數據
ALTER TABLE url TRUNCATE PARTITION p22;
把分區內的數據復制到另一張表
INSERT INTO url_8 SELECT * FROM url PARTITION(p22);
https://www.cnblogs.com/pejsidney/p/10074980.html
一.分區
本文一切基於MySql InnoDB
說了這么多,接下來說主體,先說分區,因為之前博主寫過一篇MySql分區的博客所以這里不會多費筆墨來寫,具體見:https://www.cnblogs.com/GrimMjx/p/10526821.html
2.1 實現方式
具體如何實現上面鏈接里有寫,這里只需記住如果表中存在主鍵或唯一索引時,分區列必須是唯一索引的一個組成部分。
這個是數據庫分的,應用透明,代碼無需修改任何東西。
2.2 內部文件
先去data目錄,如果不知道目錄位置的可以執行:
接下來看下內部文件:
從上圖我們可以看出,有2中類型的文件,.frm文件和.ibd文件
- .frm文件:表結構文件
- .ibd文件:InnoDB中,索引和數據都在同個文件.ibdata(你的執行結果可能是.MYD索引文件和.MYI數據文件,沒關系,這是MyIsAm存儲引擎,對應着InnoDB的.ibd文件)。因為Order這張表分為5個區,所以有5個這樣的文件
- .par文件:你執行的結果可能有.par文件也可能沒有。注意:從MySql 5.7.6開始,不再創建.par分區定義文件。分區定義存儲在內部數據字典中。
2.3 數據處理
分區表后,提高了MySql性能。如果一張表的話,那就只有一個.ibd文件,一顆大的B+樹。如果分表后,將按分區規則,分成不同的區,也就是一個大的B+樹,分成多個小的樹。
(PS:如果想研究一顆聚集索引B+樹可以放多少行數據,請看:https://www.cnblogs.com/GrimMjx/p/10540263.html)
讀的效率肯定提升了,如果走分區鍵索引的話,先走對應分區的輔助索引B+樹,再走對應分區的聚集索引B+樹。
如果沒有走分區鍵,將會在所有分區都會執行一次。會造成多次邏輯IO!平時開發如果想查看sql語句的分區查詢可以使用explain partitons select xxxxx語句。可以看到一句select語句走了幾個分區。