RDBのパーティションについて

今回はRDBのパーティションについてのメモ。テーブルにレコードが蓄積されていくと、レコード数がボトルネックになり、パフォーマンスが低下してしまうことがある。その際にパフォーマンスを改善する方法の一つとしてテーブルのパーティショニングが挙げられる。

パーティションとは

パーティショニングにより、表、索引または索引構成表をより細かい単位に細分化できるようになる。そのようなデータベース・オブジェクトの各単位はパーティションと呼ばれる。各パーティションには固有の名前があり、オプションで固有の記憶域特性を設定することもできる。

パーティショニングを行うことで得られるメリットは次のようになる。

  • レスポンスの向上
  • 管理性の向上
  • 可用性の向上

レスポンスの向上について

「レスポンスの向上」とは、問い合わせの処理を高速化できるという、代表的なパーティショニングのメリットである。データの特性や利用目的に合わせ、論理的にデータを区分けし、必要なパーティションだけを処理することでレスポンスの向上を図ることができる。

管理性の向上について

「管理性の向上」とは、メンテナンスがパーティション単位で行えるというデータ管理の効率化・高速化におけるメリットである。パーティショニングでは、1つの表のデータを分割し、各パーティションを独立して管理しているため、パーティション自体を小さな表のように操作できる。1つの表パーティションごとにEXPORT/IMPORT、統計情報の取得、バックアップ・リカバリ、SQL*Loaderなどのメンテナンス管理操作を実行できる。

可用性の向上について

「可用性の向上」とは、パーティション単位で独立して管理できることによる、ディスク破損などを想定した障害時の可用性におけるメリットである。
パーティション単位で独立して管理できるということは、障害が発生した場合も利点となる。あるパーティションが、メンテナンス中もしくは障害などで使用できない場合でも、そのパーティションがアプリケーションからのアクセス対象外であれば、アプリケーションの処理を継続することができる。特定のパーティションのデータに障害が発生しても、システム全体に影響はない。

パーティショニングの種類

パーティショニングの方法にはいくつか種類がある。以下に代表的なものをまとめる。

種類 分割方法 用途
RANGE(範囲) データを期間、範囲で分割 売り上げデータ、ログデータなど時系列にデータが生成され、年、四半期、月など、日付を条件にアクセスされる場合に有効例:売上日など日付データで分割
LIST(規則) 「任意の値リスト」を指定することでデータを分割 国、地域、都道府県など不連続な値を持つデータの集合を、自然な方法でグループ化し、任意のパーティションに格納する場合に有効例:東北、関東、中部など地域のパーティションに所属する都道府県のデータを分割
HASH(範囲) ハッシュ関数を使用し、データを均一に分割 レンジ、リスト化できない不連続なデータを均一に分割する場合に有効例:顧客番号、商品番号などでデータを分割
COMPOSITE(範囲+規則) レンジ+ハッシュまたはレンジ+リストの組み合わせ レンジで分割した後、より細かい単位に分割する場合に有効例:売り上げデータを週(レンジ)、製品番号(ハッシュ)で分割することで、週ごとの製品売り上げを把握するアプリケーションに有効

RANGE(範囲)

フィールド値の範囲でパーティションを作る方法。下記は、YEAR(created_at)の値がそれぞれ、1970~・1980~・1990~の範囲でパーティションを設定する例。

PARTITION BY RANGE( YEAR(created_at) ) ( //作成時間からYEAR関数で年だけ抽出
    PARTITION p0 VALUES LESS THAN (1970), //1970年以上、1979年以下
    PARTITION p1 VALUES LESS THAN (1980), //1980年以上、1989年以下
    PARTITION p2 VALUES LESS THAN (1990) //1990年以上
);

数あるパーティションの中で一番よく使われていると思われる。
視聴データ、発言履歴等、時間指定で取得される事が考えられるカラムと相性が良さげ。

LIST(規則)

カラムに含まれる値の指定リストでパーティションを作る方法。

PARTITION BY LIST(data) (
    PARTITION p0 VALUES IN (5, 10, 15),
    PARTITION p1 VALUES IN (6, 12, 18)
);

特定のグループ、属性等で分割する時に使われる。上記は、値が[5,10,15]の場合、[6,12,18]でパーティションを分けている。

HASH(範囲)

事前に決めたパーティションで、均等にデータを割り振る方法。先のRANGEとLISTに比べて大きく概念が違う。RANGEとLISTはユーザがデータの分割方法を設定するのに対して、HASHは「分割に使う値」と分割数だけ設定し、実際の分割方法はMySQLに任せる。分割方法はHASHに設定したカラムとパーティション数によって決まる。

PARTITION BY HASH( YEAR(hired) )
PARTITIONS 4;

この指定方法の場合、データの分割先の決定方法は以下のようにMOD()を使って求められる。MOD()は割り算の余りを求める関数である。

MOD(YEAR("2005-09-01"),4) //hiredが"2005-09-01" である場合

つまり、以下のようになる。

= MOD(2005,4)
= 1

上記は4つのパーティションの内、パーティション1に割り当てられる。
同じように、例えば、MOD()の余りが0であれば、パーティション0に割り当てられる。

参考
MySQL :: MySQL 5.1 リファレンスマニュアル
パーティション化の概念
MySQLのデータ分割。パーティション(Partition)とは – motsatのブログ