mysql使用 分區表使用,常用sql


 

mysql使用 分區表使用,常用sql

前言


本文的原文連接是: 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語句走了幾個分區。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM