MySQL 數據庫表分區

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

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

MySQL 數據庫支持的分庫類型為水平分區(指將同一表中不同行的記錄分配到不同的物理文件中),並不支持垂直分區(指將同一表中不同列的記錄分配到不同的物理文件中)。

MySQL 數據庫的分區是局部分區索引,一個分區中既存放了數據又存放了索引。而全局分區是指,數據存放在各個分區中,但是所有數據的索引放在一個對象中。MySQL 數據庫目前不支持全局分區。

MySQL 查看數據庫分區。

<code>SHOW VARIABLES LIKE '%partitions%';/<code>

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 分析數據檢索的分區。

<code>EXPLAIN PARTITIONS SELECT * FROM t_materiel_config/<code>
MySQL 數據庫表分區


分享到:


相關文章: