MySQL分區表


分區表是一種粗粒度,簡易的索引策略,適用於大數據的過濾場景.最適合的場景是,沒有合適的索引時,對其中幾個分區表進行全表掃描.或者只有一個分區表和索引是熱點,而且這個分區和索引能夠全部存儲在內存中.限制單表分區數不要超過150個,並且注意某些導致無法做分區過濾的細節,分區表對於單條記錄的查詢沒有優勢,需要注意這類查詢的性能.

 

分區表語法

  分區表分為RANGE,LIST,HASH,KEY四種類型,並且分區表的索引是可以局部針對分區表建立的

  創建分區表

CREATE TABLE sales (
    id INT AUTO_INCREMENT,
    amount DOUBLE NOT NULL,
    order_day DATETIME NOT NULL,
    PRIMARY KEY(id, order_day)
) ENGINE=Innodb PARTITION BY RANGE(YEAR(order_day)) (
    PARTITION p_2010 VALUES LESS THAN (2010),
    PARTITION p_2011 VALUES LESS THAN (2011),
    PARTITION p_2012 VALUES LESS THAN (2012),
    PARTITION p_catchall VALUES LESS THAN MAXVALUE);

  這段語句表示將表內數據按照order_dy的年份范圍進行分區,2010年一個區,2011一個,2012一個,剩下的一個.

  要注意如果這么做,則order_day必須包含在主鍵中,且會產生一個問題,就是當年份超過閾值,到了2013,2014時,需要手動創建這些分區

  替代方法就是使用HASH

  

CREATE TABLE sales (
    id INT PRIMARY KEY AUTO_INCREMENT,
    amount DOUBLE NOT NULL,
    order_day DATETIME NOT NULL
) ENGINE=Innodb PARTITION BY HASH(id DIV 1000000);

  這種分區表示每100W條數據建立一個分區,且沒有閾值范圍的影響

 

對於大數據而言

  對於大數據(如10TB)而言,索引起到的作用相對小,因為索引的空間與維護成本很高,另外如果不是索引覆蓋查詢,將導致回表,造成大量磁盤IO.那么對於這種情況的解決策略是:

  1.全量掃描數據,不要任何索引

  通過分區表表達式將數據定位在少量的分區表,然后正常訪問這些分區表的數據

  2.分離熱點,索引數據

  將熱點數據分離出來在一個小的分區,並對分區建立索引,對熱點數據的查詢提高效率.

 

分區表的問題

  1.NULL值使分區過濾無效

  假設按照RANGE YEAR(order_date)分區,那么如果這個表達式計算出來的時NULL值,記錄就會被存放到第一個分區.所以在查詢時加入查詢條件有可能出現NULL值,那么就會去檢查第一個分區.解決的方法可以是將第一個分區建立為NULL分區 PARTITION p_nulls VALUES LESS THAN (0),或者在MySQL5.5以后,直接使用COLUMN建立分區 PARTITION BY RANGE COLUMNS(order_date)

  2. 選擇分區的成本

  每插入一行數據都需要按照表達式篩選插入的分區地址

  3. 分區列和索引列不匹配

  如果索引列和分區列不匹配,且查詢中沒有包含過濾分區的條件,會導致無法進行分區過濾,那么將會導致查詢所有分區.

  4. 打開並鎖住所有底層表

  分區表的的查詢策略是在分區過濾之前,打開並鎖住所有底層表,這會造成額外的開銷,解決問題的方法是盡量使用批量操作,例如LOAD DATA INFILE,或者一次刪除多行數據.

 

過濾分區表的要點

  過濾分區表的WHERE條件必須是切分分區表的列,而不能帶有函數,例如只能是order_day,而不能是YEAR(order_day)


免責聲明!

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



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