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 を使用するとページ全体が中央に配置されない問題の解決方法

推薦する

CentOS 8/RHEL 8 に Cockpit をインストールして使用する方法

Cockpit は、CentOS および RHEL システムで使用できる Web ベースのサーバー管...

ウェブのさまざまなフロントエンド印刷方法: CSS はウェブページの印刷スタイルを制御します

CSS は Web ページの印刷スタイルを制御します。 CSS を使用して印刷スタイルを制御します。...

Vue でのキープアライブコンポーネントの使用例

問題の説明(キープアライブとは何か)キープアライブ 名前の通り、アクティブな状態を維持します。誰が活...

CSS3のtext-fill-colorプロパティの詳細な説明

text-fill-color とは何を意味しますか?文字通りの意味から言えば、「テキストの塗りつぶ...

nginx を使用してブルーグリーン デプロイメントをシミュレートする方法

この記事では、ブルーグリーン デプロイメントと、nginx を使用してブルーグリーン デプロイメント...

MySQL で指定エンコーディングを実装する際の落とし穴について

前面に書かれた環境: MySQL 5.7+、MySQL データベースの文字エンコードは utf8、テ...

LambdaProbe を使用して Tomcat を監視する方法

導入: Lambda Probe (旧称 Tomcat Probe) は、Apache Tomcat...

HTML でのアンカータグの使用例の共有

アンカータグの使用法:同じドキュメント内の特定の場所にリンクすることをアンカー リンクと呼びます。ア...

Linux の fsevents モジュールによって発生する npm ls エラーの解決方法の詳細な説明

Mac で開発されたプロジェクトがあり、パッケージ npm i がインストールされており、すべて正常...

VirtualBox で作成された Debian 仮想マシンは Windows ホストとファイルを共有します

用語: 1. VM: 仮想マシンステップ: 1. Windows 10 に VirtualBox 6...

Centos7にTenda U12ワイヤレスネットワークカードドライバーをインストールする際の問題を解決する

解決プロセス:方法1: CentOS7.3 のデフォルトのカーネル バージョンは低く、3.10.0-...

Vueはプルダウンとスクロールでデータを読み込む例を実装しています

目次ステップ1: インストールステップ2: 引用ステップ3: 使用Webプロジェクトでは、データを読...

Docker+Jenkinsによる自動デプロイの実現方法

Code Cloud を使用して Git コード ストレージ ウェアハウスを構築するhttps://...

CSS3 を使って本のページめくり効果を実現するサンプルコード

重要なポイント: 1. CSS3 3Dアニメーションをマスターする2. ページめくり後のページ内容の...

大量のデータをMySQLにインポートする際に発生する問題と解決策の分析

プロジェクトでは、SQL を使用してデータ分析を実行するために、大量のデータをデータベースにインポー...