MySQL 資料庫表分割槽

MySQL 資料庫在 5。1 版本時添加了對分割槽(partitioning)的支援。分割槽的過程是將一個表或索引分解成多個更小、更可管理的部分。就訪問資料庫的應用而言,從邏輯上來講,只有一個表或一個索引,但是在物理上這個表或索引可能由數十個物理分割槽組成。

MySQL 分割槽功能並不是在儲存引擎層完成的,因此不是隻有 InnoDB 儲存引擎支援分割槽,常見的儲存引擎 MyISAM、NDB 等都支援。

MySQL 資料庫支援的分庫型別為水平分割槽(指將同一表中不同行的記錄分配到不同的物理檔案中),並不支援垂直分割槽(指將同一表中不同列的記錄分配到不同的物理檔案中)。

MySQL 資料庫的分割槽是區域性分割槽索引,一個分割槽中既存放了資料又存放了索引。而全域性分割槽是指,資料存放在各個分割槽中,但是所有資料的索引放在一個物件中。MySQL 資料庫目前不支援全域性分割槽。

MySQL 檢視資料庫分割槽。

SHOW VARIABLES LIKE ‘%partitions%’;

MySQL 資料庫支援以下幾種型別的分割槽。如果表中存在主鍵/唯一索引時,分割槽列必須是主鍵/唯一索引的一個組成部分。對於 RANGE、LIST、HASH 和 KEY 這四種分割槽中,分割槽的條件是:資料必須是整型,如果不是整型,那應該需要透過函式將其轉化為整型,如 YEAR(),TO_DAYS(),MONTH() 等函式。

RANGE 分割槽:行資料基於屬於一個給定連續區間的列值被放入分割槽。

LIST 分割槽:和 RANGE 分割槽類似,只是 LIST 分割槽面向的是離散的值。

HASH 分割槽:根據使用者自定義的表示式(可以僅僅是欄位列名)的返回值來進行分割槽,返回值不能為負數。

LINEAR HASH 分割槽:線性 HASH 分割槽,使用的一個線性的2的冪(powers-of-two)演算法來確定新行插入到分割槽的什麼位置。LINEAR HASH 分割槽的優點在於,增加、刪除、合併和拆分分割槽將變得更加快捷,這有利於處理含有大量資料的表。缺點在於,與 HASH 分割槽相比,各個分割槽間資料的分佈可能不太均衡。

KEY 分割槽:和 HASH 分割槽類似,不過是根據 MySQL 資料庫內部提供的雜湊函式來進行分割槽。

LINEAR KEY 分割槽:和 LINEAR HASH 類似,分割槽的編號是透過2的冪(powers-of-two)演算法得到的。

COLUMNS 分割槽:5。5 版本後開始支援,可視為 RANGE 分割槽和 LIST 分割槽的一種進化,可以直接使用非整型的資料進行分割槽,分割槽根據型別直接比較而得,不需要轉化為整型。此外,RANGE COLUMNS 分割槽可以對多個列的值進行分割槽。對於之前的 RANGE 和 LIST 分割槽,使用者可以用 RANGE COLUMNS 和 LIST COLUMNS 分割槽進行很好的代替。

子分割槽(subpartitioning)是在分割槽的基礎上再進行分割槽,有時也稱為這種分割槽為複合分割槽(composite partitioning)。MySQL 資料庫允許在 RANGE 和 LIST 的分割槽上再進行 HASH 或 KEY 的子分割槽。進行子分割槽後,分割槽的數量應該為(分割槽數量 X 子分割槽數量)個。

MySQL 資料庫允許對 NULL 值做分割槽,視 NULL 值小於任何一個非 NULL 值(和 ORDER BY 處理 NULL 值的規則一致)。

對於 OLAP(線上分析處理) 的應用,分割槽的確是可以很好地提高查詢的效能,因為 OLAP 應用大多數查詢需要頻繁地掃描一張很大的表。假設有一張 1 億行的表,其中有一個時間戳屬性列。使用者的查詢依據時間為維度,如果按照時間戳進行分割槽,則只需要掃描對應的分割槽即可。

對於 OLTP(線上事務處理)的應用,通常不可能會獲取一張大表中 10% 的資料,大部分都是透過索引返回幾條記錄即可。因此分割槽應該非常小心,對於一張大表,一般的 B+ 樹需要 2~3 次 IO 就能檢索到資料。透過根據主鍵 ID 做 10 個 HASH 的分割槽後,對於查詢就需要掃描所有的 10 個分割槽,這無疑加重了 IO 的負擔。

我們透過 Navicat 來操作下資料庫分割槽,表 -> 右鍵點選‘設計表’ -> 選項 -> 分割區,可以看到如下內容。

MySQL 資料庫表分割槽

來看看分割槽後,磁碟中 MySQL 資料庫是怎麼儲存的。

MySQL 資料庫表分割槽

透過 EXPLAIN 分析資料檢索的分割槽。

EXPLAIN PARTITIONS SELECT * FROM t_materiel_config

MySQL 資料庫表分割槽