MySQL テーブルパーティションの使用法と基本原理の詳細な説明

MySQL テーブルパーティションの使用法と基本原理の詳細な説明

パーティションテーブルとは

MySQL はバージョン 5.1 以降、パーティショニングをサポートしています。パーティショニングとは、テーブルのデータを、月ごとなど何らかの方法で、より小さく管理しやすい複数の部分に分割することですが、論理的には依然としてテーブルです。

パーティション テーブルが登場する前は、すべてのデータが 1 つのファイルに保存されていました。データの量が多すぎると、データを照会するときに必然的に大量の IO 操作が必要になりました。パーティション テーブルの使用後は、各パーティションに異なるデータが格納されます。これにより、io が削減されるだけではありません。また、データへのアクセスを高速化することもできます。

MySQL のパフォーマンスを確保するには、単一の MySQL テーブルが大きすぎないようにすることをお勧めします。推奨事項は、単一のテーブルは 2G 未満、レコード数は 1,000 万未満、データベースは 10 個、テーブルは 100 個にすることです。行内のレコード数が非常に少ない場合は、レコード数を大きくすることができます。そうでない場合、レコード数が数百万に達したときに処理が遅くなり始める可能性があります。

では、業務量が増えてデータがボトルネックになった場合はどうすればいいのでしょうか。分散データベースを使用するだけでなく、データベースやテーブルを自分で分割したり、MySQL のパーティショニング機能を使用して実現することもできます。

パーティション テーブルは、分割統治の概念をサポートするために作成されました。パーティション テーブルは非常に便利ですが、まだ多くの人がそれを知りません。
テーブルがパーティション テーブルとして設定されると、データ ファイル .idb のファイル名に # 記号が追加され、これがパーティション テーブルであることが示されます。

パーティションテーブルの適用シナリオ

  1. テーブルが大きすぎてメモリに格納できないか、テーブルの最後の部分にのみホット データが含まれ、残りは履歴データです。
  2. パーティションテーブル内のデータはメンテナンスが容易になり、大量のデータを一括で削除できる
  3. 独立したパーティションの最適化、チェック、修復など
  4. パーティションテーブルのデータは異なるデバイスに分散される可能性があり、複数のハードウェアデバイスを効率的に使用することはできません。
  5. 独立したパーティションをバックアップおよび復元できます。

パーティションテーブルの制限

  1. テーブルには最大 1024 個のパーティションを含めることができ、バージョン 5.7 以降では 8196 個のパーティションを含めることができます。
  2. MySQL の初期の頃は、パーティショニング式は整数または整数を返す式である必要がありました。MySQL 5.5 では、一部のシナリオで列を直接パーティショニングに使用できます。
  3. パーティションテーブルでは外部制約を使用できません
  4. パーティション列を変更しないのが最善です
  5. パーティション フィールドに主キーまたは一意のインデックス列がある場合は、次のようにすべての主キー列と一意のインデックス列を含める必要があります。
-- すべての主キーを含むパーティションを作成する create table user_11(
  id bigint(20) が null ではない、
  名前varchar(20)、
  年齢 int(3)、
	主キー (`id`,`age`)
)
-- 範囲列(id、age)でパーティションパーティションを作成します(
  パーティション p00 の値が (6,30) 未満の場合、6 未満の値は P0 パーティションにあります。パーティション p11 の値が (11,40) 未満の場合、11 未満の値は p1 パーティションにあります。パーティション p22 の値が (16,50) 未満の場合、16 未満の値は p2 パーティションにあります。パーティション p33 の値が (9999,9999) 未満の場合、21 を超える値は p3 パーティションにあります。または、それより大きい値を使用します。

-- すべての一意のキーを含むパーティションを作成する create table user_22(
  id bigint(20) が null ではない、
  名前varchar(20)、
  年齢 int(3) が null でない、
	ユニークキー only_one_1(age,id )
)
-- 範囲列(id、age)でパーティションパーティションを作成します(
  パーティション p000 の値が (6,30) 未満の場合、6 未満の値は P0 パーティションにあります。パーティション p111 の値が (11,40) 未満の場合、11 未満の値は p1 パーティションにあります。パーティション p222 の値が (16,50) 未満の場合、16 未満の値は p2 パーティションにあります。パーティション p333 の値が (9999,9999) 未満の場合、21 を超える値は p3 パーティションにあります。または、それより大きい値を使用します。

パーティションタイプ

  1. 範囲分割
  2. リストパーティション
  3. 列分割
  4. ハッシュパーティション
  5. キーパーティション
  6. サブパーティション

パーティションテーブルの使用

1. 範囲分割

次の例では、年齢がパーティション分割されています。

従業員テーブルを作成する(
id bigint(20) が null ではない、
年齢 int(3) が null でない、
名前varchar(20)
)
-- 範囲(年齢)でパーティションを作成(
  パーティション p0 値が (6) 未満 -- 6 未満の値は P0 パーティションにあります。パーティション p1 値が (11) 未満 -- 11 未満の値は p1 パーティションにあります。パーティション p2 値が (16) 未満 -- 16 未満の値は p2 パーティションにあります。パーティション p3 値が (21) 未満 -- 21 未満の値は p3 パーティションにあります。

作成後、データフォルダにパーティションファイルが表示されます。

[root@VM_0_5_centos テスト]# pwd
/var/lib/mysql/テスト
[root@VM_0_5_centos テスト]# ll
総使用量 8741504
-rw-rw---- 1 mysql mysql 61 2018年10月31日 db.opt
-rw-rw---- 1 mysql mysql 8614 8月1日 21:30 employees.frm
-rw-rw---- 1 mysql mysql 32 8月1日 21:30 employees.par
-rw-rw---- 1 mysql mysql 98304 8月1日 21:30 従業員#P#p0.ibd
-rw-rw---- 1 mysql mysql 98304 8月1日 21:30 従業員#P#p1.ibd
-rw-rw---- 1 mysql mysql 98304 8月1日 21:30 従業員#P#p2.ibd
-rw-rw---- 1 mysql mysql 98304 8月1日 21:30 従業員#P#p3.ibd

年齢フィールドには 21 未満の数字しか挿入できないため、21 という数字を挿入するとエラーが報告されます。

mysql> 従業員 (ID、名前、年齢) の値を挿入します (1、'yexindong'、21);
エラー 1526 (HY000): テーブルに値 21 のパーティションがありません

したがって、この問題を解決するには、テーブルを作成するときにこれを行うことができます。最大値にはmaxvalueを使用します。maxvalueの値は28個の9、つまり999999999999999999999999999999であると言われています。

従業員テーブルを作成する(
id bigint(20) が null ではない、
年齢 int(3) が null でない、
名前varchar(20)
)
-- 範囲(年齢)でパーティションを作成(
  パーティション p0 の値が (6) 未満 -- 6 未満の値は P0 パーティションにあります。パーティション p1 の値が (11) 未満 -- 11 未満の値は p1 パーティションにあります。パーティション p2 の値が (16) 未満 -- 16 未満の値は p2 パーティションにあります。パーティション p3 の値が maxvalue 未満 -- 16 を超える値は p3 パーティションにあります。または、それより大きい値を使用します。

時間範囲の分割

従業員テーブルを作成する(
    id INT NOT NULL、
    fname VARCHAR(30)、
    lname VARCHAR(30)、
    雇用日 NULL ではない デフォルト '1970-01-01',
    区切られた日付 NULL ではない デフォルト '9999-12-31'、
    ジョブコード INT、
    ストアID INT
)
範囲によるパーティション ( 年(区切り) ) (
    PARTITION p0 VALUES LESS THAN (1991) -- 1991 年より前のデータはパーティション P0 にあります。PARTITION p1 VALUES LESS THAN (1996) -- 1996 年より前のデータはパーティション P1 にあります。PARTITION p2 VALUES LESS THAN (2001) -- 2001 年より前のデータはパーティション P2 にあります。PARTITION p3 VALUES LESS THAN MAXVALUE -- 2001 年より後のデータはパーティション P3 にあります。

テーブルメンバーの作成(
    名 VARCHAR(25) NOT NULL,
    姓 VARCHAR(25) NOT NULL,
    ユーザー名 VARCHAR(16) NOT NULL,
    電子メール VARCHAR(35)、
    参加日がNULLではありません
)
範囲列によるパーティション(結合) (
    パーティション p0 の値は ('1960-01-01') より小さいです。
    パーティション p1 の値は ('1970-01-01') より小さいです。
    パーティション p2 の値は ('1980-01-01') より小さいです。
    パーティション p3 の値は ('1990-01-01') より小さいです。
    パーティション p4 の値が MAXVALUE 未満です
);

2. リストパーティション(リストパーティション)

リスト パーティション分割と範囲パーティション分割の最大の違いは、リスト パーティション分割は等しいのに対し、範囲パーティション分割は特定の範囲内である点です。

従業員テーブルを作成する(
    id INT NOT NULL、
    fname VARCHAR(30)、
    lname VARCHAR(30)、
    雇用日 NULL ではない デフォルト '1970-01-01',
    区切られた日付 NULL ではない デフォルト '9999-12-31'、
    ジョブコード INT、
    ストアID INT
)
PARTITION BY LIST(store_id) (
    PARTITION pNorth VALUES IN (3,5,6,9,17) -- 3,5,6,9,17 の値は、pNorth パーティションに配置されます。 PARTITION pEast VALUES IN (1,2,10,11,19,20) -- 1,2,10,11,19,20 の値は、pEast パーティションに配置されます。 PARTITION pWest VALUES IN (4,12,13,14,18) -- 4,12,13,14,18 の値は、pWest パーティションに配置されます。 PARTITION pCentral VALUES IN (7,8,15,16) -- 7,8,15,16 の値は、pCentral パーティションに配置されます。

3. 列分割

列パーティションは、範囲パーティションとリスト パーティションのバリエーションです。つまり、列パーティションは、範囲パーティションとリスト パーティションにカプセル化されています。唯一の違いは、列パーティションにはデータ型の制限がないことです。つまり、範囲パーティションとリスト パーティションは列パーティションです。

4. ハッシュパーティション

ハッシュ パーティショニングでは、範囲やリストを指定する必要はなく、挿入する値を動的に割り当てて、どのパーティションに挿入するかを決定します。これは、hashMap の原理と非常によく似ています。違いは、hashMap はハッシュ衝突問題を解決するために摂動関数を使用するのに対し、MySQL のハッシュ パーティショニングはモジュロ演算によって結果を直接取得し、指定された位置のパーティションに値を挿入することです。

-- 共通フィールドのパーティション分割 CREATE TABLE employees (
    id INT NOT NULL、
    fname VARCHAR(30)、
    lname VARCHAR(30)、
    雇用日 NULL ではない デフォルト '1970-01-01',
    区切られた日付 NULL ではない デフォルト '9999-12-31'、
    ジョブコード INT、
    ストアID INT
)
ハッシュによるパーティション(store_id)
PARTITIONS 5;--5つのパーティション0、1、2、3、4を作成します

-- 時間タイプのパーティションを作成する CREATE TABLE employees (
    id INT NOT NULL、
    fname VARCHAR(30)、
    lname VARCHAR(30)、
    雇用日 NULL ではない デフォルト '1970-01-01',
    区切られた日付 NULL ではない デフォルト '9999-12-31'、
    ジョブコード INT、
    ストアID INT
)
ハッシュによるパーティション(YEAR(採用))
PARTITIONS 4; -- 0、1、2、3の4つのパーティションを作成します。

5. 秘密鍵パーティション(鍵パーティション)

キーパーティショニングはあまり使用されていない

-- 主キーによるパーティション CREATE TABLE k1 (
    id INT NOT NULL 主キー、
    名前 VARCHAR(20)
)
キーによるパーティション()
PARTITIONS 2; -- P0とP1という名前の2つのパーティションを作成します。これはハッシュパーティションの変形です。保存方法はハッシュパーティションと同じです。 -- 一意のキーでパーティションを作成します CREATE TABLE k1 (
    id INT NOT NULL、
    名前 VARCHAR(20)、
    ユニークキー (id)
)
キーによるパーティション()
パーティション 3;-- 3 つのパーティション (p0、p1、p2) を作成します。

-- パーティション分割の主キーフィールドを指定する CREATE TABLE tm1 (
    s1 CHAR(32) 主キー
)
キーによるパーティション(s1)
PARTITIONS 10; -- 10個のパーティションを作成する

6. サブパーティション

サブパーティション化は、パーティション化に基づいてパーティション化することとして理解できます。たとえば、テーブルが 3 つのパーティションに分割され、各パーティションに 3 つのサブパーティションがある場合、合計で 3 * 3 = 9 個のパーティションが存在します。

 -- テーブルには 3 つのパーティションがあり、各パーティションには 2 つのサブパーティションがあるため、合計で 6 つのパーティションがあります。CREATE TABLE ts (id INT, purchased DATE)
    範囲によるパーティション(年(購入))
    ハッシュによるサブパーティション(TO_DAYS(購入日))
    サブパーティション 2 (
        パーティション p0 値が (1990) 未満の場合、
        パーティション p1 の値は (2000) 未満です。
        パーティション p2 の値が MAXVALUE 未満です
    );

mysqlデータファイルを入力すると、6つのファイルがあることがわかります。名前の通り、6つのパーティションが生成されます。

-rw-rw---- 1 mysql mysql 98304 8月2日 22:37 ts#P#p0#SP#p0sp0.ibd
-rw-rw---- 1 mysql mysql 98304 8月2日 22:37 ts#P#p0#SP#p0sp1.ibd
-rw-rw---- 1 mysql mysql 98304 8月2日 22:37 ts#P#p1#SP#p1sp0.ibd
-rw-rw---- 1 mysql mysql 98304 8月2日 22:37 ts#P#p1#SP#p1sp1.ibd
-rw-rw---- 1 mysql mysql 98304 8月2日 22:37 ts#P#p2#SP#p2sp0.ibd
-rw-rw---- 1 mysql mysql 98304 8月2日 22:37 ts#P#p2#SP#p2sp1.ibd

パーティションを追加する

-- リスト パーティションを追加します。alter table titles add partition(partition p7 values ​​in('CEO'));

パーティションテーブルの原理

パーティション テーブルは、ハンドル オブジェクトによっても識別される複数の関連する基礎テーブルによって実装されます。各パーティションに直接アクセスできます。ストレージ エンジンは、通常のテーブルを管理するのと同じ方法でパーティションの基になるテーブルを管理します (すべての基になるテーブルは同じストレージ エンジンを使用する必要があります)。パーティション テーブルのインデックスは、基になる各テーブルに同一のインデックスを追加するだけです。ストレージ エンジンの観点から見ると、基になるテーブルは通常のテーブルと違いはなく、ストレージ エンジンはこれが通常のテーブルなのか、パーティション化されたテーブルの一部なのかを認識する必要はありません。

パーティション テーブルの操作は、次の操作ロジックに従って実行されます。

クエリを選択

パーティション化されたテーブルをクエリする場合、パーティション レイヤーは最初にすべての基礎テーブルを開いてロックします。オプティマイザーは最初に一部のパーティションをフィルターできるかどうかを判断し、対応するストレージ エンジン インターフェイスを呼び出して各パーティションのデータにアクセスします。

挿入操作

レコードを書き込むとき、パーティション レイヤーはまずすべての基礎テーブルを開いてロックし、次にどのパーティションがレコードを受け入れるかを決定し、対応する基礎テーブルにレコードを書き込みます。

削除操作

レコードを削除する場合、パーティション レイヤーは最初にすべての基礎テーブルを開いてロックし、次にデータに対応するパーティションを決定し、最後に対応する基礎テーブルを削除します。

更新操作

レコードを更新する場合、パーティション レイヤーは最初にすべての基礎テーブルを開いてロックします。MySQL は最初に更新するレコードがどのパーティションにあるかを判断し、次にデータを取得して更新し、次に更新されたデータをどのパーティションに置くかを判断します。最後に、基礎テーブルに書き込み、ソース データが配置されている基礎テーブルを削除します。

一部の操作ではフィルタリングがサポートされています。たとえば、レコードを削除する場合、MySQL はまずレコードを見つける必要があります。where 条件がパーティション式と一致する場合、このレコードを含まないすべてのパーティションをフィルタリングできます。これは更新にも有効です。挿入操作の場合、1 つのパーティションのみがヒットし、他のパーティションは除外されます。 MySQL はまずレコードがどのパーティションに属しているかを判断し、他のパーティションを操作することなく、対応するパーティション テーブルにレコードを書き込みます。

各操作では「まず基礎となるすべてのテーブルを開いてロックします」が、これは処理中にパーティション テーブルがテーブル全体をロックすることを意味するものではありません。InnoDB など、ストレージ エンジンが行レベルのロックを独自に実装できる場合、対応するテーブル ロックはパーティション レベルで解除されます。

パーティションテーブルの使い方

  1. ログシステムはパーティション分割できます。一般的に、ログの数は比較的多く、年または月ごとにパーティション分割されます。一般的に、ログシステムでは、一定期間の履歴レコードを照会する必要があります。データ量が膨大であるため、フルテーブルスキャンは使用できません。フルテーブルスキャンでは、大量のランダムIOが発生します。データ量が多すぎると、インデックスが機能しません。このとき、問題を解決するにはパーティション分割を検討する必要があります。
  2. パーティショニングは、データ量が多いときだけ必要なわけではありません。データ量が少ないときにもパーティショニングを使用できます。データ量が少ないのはどのようなシナリオですか?答えは、毎回クエリするデータがバッチである場合にパーティション分割を使用できるということです。たとえば、辞書、ビジネス辞書、ユーザー タイプ辞書は通常、同じテーブルに格納されます。また、クエリを実行するたびに、1 つのビジネスまたは 1 つのユーザー タイプだけでなく、ビジネスまたはユーザー タイプ全体をクエリします。これはバッチであり、これを実現するためにもパーティション分割を使用できます。
  3. パーティションを使用した後は、インデックスは必要ありません。パーティションは通常、範囲クエリに使用され、範囲クエリではインデックスを使用する必要がないためです。データが異なるパーティションに分散されています。
  4. インデックスを使用する場合は使用できますが、ホット データとコールド データを分離する必要があります。ホット データとは、頻繁にクエリされるデータです。アクセスを高速化するには、ホット データ テーブルにインデックスを追加します。

予防

  1. NULL 値はパーティション フィルタリングを無効にします。パーティションには列名が必要であり、列名に NULL 値が含まれていないことを確認する必要があります。
  2. パーティション列とインデックス列が同じ列でない場合、クエリはパーティション フィルタリングを実行できません。たとえば、id フィールドと age フィールドの両方にインデックスが付けられている場合、パーティション分割時にこれらの 2 つの列をパーティション列として設定するのが最適です。PARTITION BY RANGE COLUMNS(id,age)
  3. パーティション化されたテーブルの追加、削除、および変更にかかるコストは非常に高くなります。テーブルが追加、削除、または変更されるたびに、基礎となるすべてのテーブルが開かれ、ロックされます。1 つのテーブルがロックされている限り、他の操作は実行できません。
  4. パーティションを保守する場合、コストが非常に高くなる可能性があります。特に、パーティションを変更する必要がある場合は、コストが最も高くなります。

要約する

MySQL テーブル パーティションの使用と基本原理に関するこの記事はこれで終わりです。MySQL テーブル パーティションの基本原理の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQL データテーブルのパーティション戦略と利点と欠点の分析
  • MySQL の高度な機能 - データ テーブル パーティショニングの概念とメカニズムの詳細な説明
  • MySQL データベース テーブルのパーティション分割に関する考慮事項 [推奨]
  • MySQLのテーブルパーティショニング技術の詳細な分析
  • MySQL データ テーブル パーティション テクノロジーの簡単な分析
  • MySQLテーブルパーティショニングの詳細な説明
  • MySQL テーブル パーティションを作成する方法
  • MySQL のテーブルパーティショニングを 1 つの記事で理解する

<<:  CSS プロパティ display:flow-root 宣言を 1 つの記事でマスターする

>>:  HTML で margin:0 auto を使用するとページ全体が中央に配置されない問題の解決方法

推薦する

CentOS6.8 は cmake を使用して MySQL5.7.18 をインストールします。

オンライン情報を参考に、cmakeを使用してCentOS6.8サーバーにMySQL5.7.18をイン...

Linuxはjoin -a1を使用して2つのファイルを結合します

次の2つのファイルを結合するには、それらを結合して1.txtに結合します。 # 1.txt ジェリー...

MySQL5.7 並列レプリケーションの原理と実装

データ操作とメンテナンスに少しでも知識のある人なら、MySQL 5.5 以前では再生に単一の SQL...

Raspberry Pi 3B+ に 64 ビット Ubuntu システムと Docker ツールをインストールする詳細な手順

Raspberry Pi 3B に 64 ビット アプリケーション (64 ビット JDK など) ...

Webpack-cliが正常にインストールされたら、詳細についてはwebpack -vエラーケースを確認してください。

目次質問1. webpack webpack-cliをインストールする2. webpackのバージョ...

LeetCode の SQL 実装 (184. 部門内で最も高い給与)

[LeetCode] 184. 部門最高給与従業員テーブルにはすべての従業員が保存されます。すべて...

mysqlパラメータsql_safe_updatesを使用して更新/削除範囲を制限する方法の詳細な説明

序文皆さんご存知のとおり、MySQL の運用・保守において、更新/削除条件が誤っているためにデータが...

MySQLストアドプロシージャを変更する詳細な手順

序文実際の開発では、ビジネス要件が変更されることが多いため、ストアド プロシージャの特性を変更するこ...

アリババの中秋節ロゴとウェブサイトのデザインプロセス

<br />まずアイデアを考え、次にスケッチを描き、次にマウスでスケッチし、最後にフラッ...

Linux mpstat コマンドの使用方法の詳細な説明

1. mpstatコマンド1.1 コマンド形式 mpstat [ -A ] [ -u ] [ -V ...

MySQL 最適化の概要 - クエリエントリの合計数

1. COUNT(*) と COUNT(COL) COUNT(*)は通常、主キーに対してインデックス...

React Fragment の紹介と詳しい使い方

目次序文フラグメントの動機React Fragment の紹介と使用<React.Fragme...

Linux 上で Python3.6 をコンパイルしてインストールするための詳細なチュートリアル

1. まず、公式ウェブサイト https://www.python.org/downloads/so...

docker pullがリセットされる問題を解決する

この記事では、docker pull がリセットされる問題を解決する方法を紹介し、皆さんと共有します...

ウェブデザインでは、まずウェブサイトの包括的なイメージの位置付けが必要です。

⑴ 内容によって形式が決まります。まず内容を充実させ、次にブロックに分割し、トーンを決め、最後に細部...