mysqlデータベースパーティション

記事ディレクトリ


私がインストールした mysql のバージョンはコミュニティ版 8.0.34 ですが、以降 SQL 実行を伴う場合はこのバージョンに基づいて説明します。

1. パーティションとは

いわゆるパーティショニングとは、テーブルを操作と保存のために複数のブロックに分割することにより、各操作に必要なデータを削減し、パフォーマンスを向上させることです。これはアプリケーションに対して透過的です。論理的にはテーブルが 1 つだけありますが、物理的にはこのテーブルは複数の物理パーティションで構成されている場合があります。各パーティションは独立したオブジェクトであり、個別に処理できます。要するに:未分区的表所有数据物理层面存储在同一个文件中,分区的表会按分区数量存储到不同的文件中,提高查询效率

物理レベルでのパーティショニングと非パーティショニングの違いは次のとおりです。
ここに画像の説明を挿入します

パーティショニングはテーブル設計パターンであり、正しいパーティショニングによりデータベースのクエリ効率が大幅に向上し、より高品質な SQL プログラミングを完成させることができます。しかし、パーティショニングを誤って使用すると、壊滅的な結果を招く可能性があります。

MySQL データベースは、バージョン 5.1 以降でパーティショニングのサポートを追加しました。パーティショニング機能はストレージ エンジン層では完了しません。一般的なストレージ エンジン InnoDB、MyISAM、NDB などはすべてパーティショニングをサポートしています。ただし、すべてのストレージ エンジンがこれをサポートしているわけではなく、たとえば、CSV、FEDORATED、MERGE などはパーティショニングをサポートしていません。mysql8 以降のパーティショニングをサポートしているのは、ストレージ エンジン InnoDB と NDB のみです。

パーティショニングの詳細については、公式 Web サイトを参照してください。

1.1. パーティションの種類(横パーティション、縦パーティション)

  • 水平パーティショニング: テーブルの行を異なる物理パーティションに割り当てることができます。
  • 垂直パーティション化: テーブルの異なる列を異なる物理パーティションに割り当てます。(MySQL 8.0 は垂直パーティショニングをサポートしていません。また、現時点では MySQL に垂直パーティショニングを導入する予定はありません)

さらに、MySQL データベースのパーティションはローカル パーティション インデックスであり、データとインデックスの両方が 1 つのパーティションに保存されます。グローバル パーティショニングとは、データは各パーティションに格納されますが、すべてのデータのインデックスは 1 つのオブジェクトに配置されることを意味します。現在、MySQL データベースはグローバル パーティショニングをサポートしていません。

1.2. テーブルパーティショニングの長所と短所

パーティショニングの利点:

  1. 1 つのテーブルにさらに多くのデータを保存できます。
  2. パーティション分割されたテーブルのデータは保守が容易です。パーティション全体をクリアすることで大量のデータをバッチで削除したり、新しく挿入されたデータをサポートするために新しいパーティションを追加したりできます。さらに、独立したパーティションに対して最適化、検査、修復などの操作を実行することもできます。
  3. 一部のクエリは、クエリ条件から少数のパーティションのみに該当すると判断でき、速度が非常に速くなります (クエリ条件はできるだけ少ないパーティションをスキャンします)。
  4. パーティション テーブルのデータは異なる物理デバイスに分散することもできるため、複数のハードウェア デバイスを効率的に利用できます。
  5. パーティション テーブルを使用すると、InnoDB 内の単一インデックスへの相互排他的アクセスや ext3 ファイル システム内の i ノード ロックの競合など、特定の特殊なボトルネックを回避できます。
  6. 個々のパーティションをバックアップおよび復元できます。
  7. 对于查询分区表的SELECT语句,建议包含分区列,这样就只会在这个分区内查询,不用全表搜索,效率更快

パーティショニングの制限と欠点:

  1. MySQL 5.6.7 より前のバージョンでは、テーブルには最大 1024 個のパーティションを含めることができますが、5.6.7 以降では、テーブルに最大 8192 個のパーティションを含めることができます。
  2. 如果一个表有主键,那么MYSQL的分区字段必须包含在主键内,也就是分区字段必须是主键的一部分或者全部,不能以非主键的字段作为分区字段。当然,也可以为没有主键的表建立分区。
  3. パーティションテーブルでは外部キー制約を使用できません。
  4. NULL 値を指定すると、パーティションのフィルタリングが無効になります。
  5. すべてのパーティションは同じストレージ エンジンを使用する必要があります。

1.3. テーブルパーティショニングとテーブルパーティショニングの違い

テーブル分割: 特定のルールに従ってテーブルを複数の異なるテーブルに分解することを指します。たとえば、銀行取引記録は、時間に基づいて月ごとに複数のテーブルに分割されます。

テーブル分割とパーティショニングの違いは、パーティショニングでは論理的にテーブルが 1 つだけであるのに対し (物理レベルでは複数のテーブル ファイルがあります)、テーブル分割では 1 つのテーブルが複数のテーブルに分割されることです。

以下のように: パーティション テーブルを作成すると、物理レベルで複数のテーブル ファイルが存在します。

create table if not exists product
(
	id int not null ,
	name varchar(20) null comment '商品名称',
	type varchar(20) not null comment '商品类型',
    primary key(id,type)
) partition by key(type) partitions 4;  -- 根据商品类型进行分区

ここに画像の説明を挿入します

2. パーティションの種類

パーティショニング方法はレンジパーティショニング、リストパーティショニング、ハッシュパーティショニング、キーパーティショニングの4種類に分類できます。
(1) 範囲パーティショニング:ID 1~100 をまとめて割り当てる、ID 101~200 をまとめて割り当てる、ID 201~300 をまとめて割り当てる、など、月ごとなどの連続した範囲でパーティションを分割します
。 : 国、地方、都市などの離散値リストに従ってパーティションを分割します。たとえば、フィールドに応じて値 1、3、5 をまとめ、値 2、4、6 をまとめます。 (3
) ハッシュ分割: ユーザーごとにデータをハッシュ分割します。定義されたルール。
(4) キー パーティション: ハッシュ パーティションに似ていますが、データは MySQL エンジン独自のルールに従って処理されます。
(5) 列パーティション: バージョン 5.5 より前の RANGE、LIST、および HASH パーティションでは、パーティション キーが int である必要があります。MySQL 5.5 以降では、非整数の RANGE および LIST パーティション、つまり、範囲列とリスト列 (文字列は可能) をサポートしています。パーティションに使用されます)。

パーティション テーブルを使用するときは、次の詳細に注意する必要があります。
(1) テーブルに主キーまたは一意キーがある場合、パーティション化列は副キーまたは一意キーのコンポーネントである必要があります。パーティション関数 列は pk キーまたは uk キーのサブセットのみにすることができます
(2) テーブルに主キーまたは一意のキーがない場合は、任意の列をパーティション列として指定できます
(3) パーティション化されたテーブルを使用する場合は、次の値を指定する必要がありますパーティションリスト。パーティション列のデータ型はパーティション メソッドに対応している必要があります。
(4) 複数レベルのパーティションを作成する必要がある場合は、第 1 レベルのパーティションを作成するときに、第 2 レベルのパーティションの情報を括弧内に記述するだけです。
(5) パーティションテーブルをクエリする SELECT ステートメントにはパーティション列を含める必要があり、特定のパーティションのデータのみをクエリする場合は、「SELECT * FROM order PARTITION (p2010)」に似た構文を使用する必要があります。
(6) 分区的命名默认是p0,p1,p2.........并且分区名称不区分大小写
(6)全表查询时,分区表默认排序是按分区排序,而不是按主键排序

2.1. RANGE パーティション (公式ドキュメント)

RANGE パーティショニングは最も一般的に使用されるタイプのパーティショニングで、指定された連続範囲に属する列値に基づいて複数の行をパーティションに割り当てます。これらの間隔は連続的である必要があり、互いに重なることはできず、VALUES LESS THAN演算子を使用して定義されます。不使用COLUMNS关键字时RANGE括号内必须为整数字段名或返回确定整数的函数。

RANG パーティションの機能:

  • パーティション キー値の範囲に従って、テーブルの異なるパーティションに異なるデータを格納します。
  • 複数のパーティションのパーティション キー値の範囲は連続している必要がありますが、重複することはできません。
  • デフォルトでは VALUES LESS THAN 属性が使用されますが、各パーティションには指定された値は含まれません。

2.1.1. RANGE パーティションの作成

次の例では、id 列を持つインターバル パーティション テーブルを作成します。id が 10 未満の場合、データは p0 パーティションに挿入されます。id が 10 以上 20 未満の場合、データは p0 パーティションに挿入されます。 p1パーティション。コードは以下のように表示されます。

create  table  t(
  id int
)engine=innodb
partition by range(id)(
     partition  p0  values  less  than(10),-- 存放<10的数据
     partition  p1  values  less  than(20)-- 存放>=10  <20的数据
);

パーティションを作成した後、データを挿入すると、mysql はデータの値に基づいて対応するパーティションにデータを自動的に挿入します。

insert into t values (9);
insert into t values (11);

上記のデータを挿入した後、パーティションを表示します。

-- 查看p0分区的数据
SELECT * FROM t PARTITION (p0);

結果は次のとおりです。
ここに画像の説明を挿入します

テーブルをパーティション分割した後、挿入されるデータの値はパーティションの定義に厳密に準拠する必要があります。どのパーティションにも属さない値を挿入すると、MySQL データベースは直接エラーを報告します。次のように:
ここに画像の説明を挿入します
[HY000][1526] Table has no partition for value 40

この状況の発生を回避するには、MAXVALUE 値を持つパーティションをパーティションに追加します。MAXVALUE は正の無限大として理解できるため、20 以上 MAXVALUE 未満のすべての値が p2 に配置されます。パーティション。

alter table t add partition(partition p2 values less than maxvalue);

このとき、>=20 のすべての値が p2 パーティションに挿入されます。

2.1.2. フィールドタイプの日付とタイムスタンプの範囲分割

公式 Web サイトからユースケースを直接引用しました。詳細については、公式 Web サイトの
RANGE Partitioningを参照してください。

 CREATE TABLE members (
    firstname VARCHAR(25) NOT NULL,
    lastname VARCHAR(25) NOT NULL,
    username VARCHAR(16) NOT NULL,
    email VARCHAR(35),
    joined DATE NOT NULL
)
PARTITION BY RANGE( YEAR(joined) ) (
    PARTITION p0 VALUES LESS THAN (1960),
    PARTITION p1 VALUES LESS THAN (1970),
    PARTITION p2 VALUES LESS THAN (1980),
    PARTITION p3 VALUES LESS THAN (1990),
    PARTITION p4 VALUES LESS THAN MAXVALUE
);
CREATE TABLE quarterly_report_status (
    report_id INT NOT NULL,
    report_status VARCHAR(20) NOT NULL,
    report_updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)
PARTITION BY RANGE ( UNIX_TIMESTAMP(report_updated) ) (
    PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-01-01 00:00:00') ),
    PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-04-01 00:00:00') ),
    PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-07-01 00:00:00') ),
    PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2008-10-01 00:00:00') ),
    PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-01-01 00:00:00') ),
    PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-04-01 00:00:00') ),
    PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-07-01 00:00:00') ),
    PARTITION p7 VALUES LESS THAN ( UNIX_TIMESTAMP('2009-10-01 00:00:00') ),
    PARTITION p8 VALUES LESS THAN ( UNIX_TIMESTAMP('2010-01-01 00:00:00') ),
    PARTITION p9 VALUES LESS THAN (MAXVALUE)
);

2.2. LISTパーティション(公式ドキュメント

LIST パーティショニングは RANGE パーティショニングに似ていますが、異なる点は、LIST パーティショニングは連続値ではなく、離散値セット内の特定の値に一致する列値に基づいて選択されることです。

LIST パーティショニングは、「 PARTITION BY LIST(expr) 」を使用して実現されます。「expr」は列値または列値に基づく式であり、整数値を返します。その後、「 VALUES IN (value_list)」方法で定義します。各パーティション。「value_list」はカンマで区切られた整数のリストです。

LIST パーティションの特徴:

  • パーティションキー値のリストによるパーティション化
  • 範囲パーティション化と同様に、各パーティション内のリスト値を繰り返すことはできません。
  • データの各行は、対応するパーティション リストを見つけることができる必要があります。見つからない場合、データの挿入は失敗します。
CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LIST(store_id) (
    PARTITION pNorth VALUES IN (3,5,6,9,17),
    PARTITION pEast VALUES IN (1,2,10,11,19,20),
    PARTITION pWest VALUES IN (4,12,13,14,18),
    PARTITION pCentral VALUES IN (7,8,15,16)
);

2.3. HASHパーティション(公式ドキュメント

HASH パーティションの特徴:

  • MOD の値 (パーティション キー、パーティション数) に応じて、データ行をテーブルの異なるパーティションに格納します。
  • データをさまざまなパーティションに均等に分散できる
  • HASH パーティションのキー値は INT 型の値である必要があります。または、関数を通じて INT 型に変換できます。
CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY HASH( YEAR(hired) )
PARTITIONS 4;

従業員にレコードを挿入し、その雇用値が「2005-09-15」である場合、そのレコードが保存されるパーティションは次のようになります。

MOD(YEAR('2005-09-01'),4)
=  MOD(2005,4)
=  1

2.4、キーパーティション

キーによるパーティショニングは、ハッシュによるパーティショニングと似ていますが、ハッシュ パーティショニングではユーザー定義の式が使用され、キー パーティショニングに使用されるハッシュ関数が MySQL サーバーによって提供される点が異なります。MySQL Cluster はこの目的で MD5() を使用します。他のストレージ エンジンを使用するテーブルの場合、サーバーは独自の内部ハッシュ関数を使用します。

キー分割は、ハッシュ分割テーブルを作成する方法と似ています。主な違いは次のとおりです。

  • HASH の代わりに KEY を使用します。
  • KEY は、0 個以上の列名のリストのみを受け入れます。パーティション キーとして使用される列には、テーブルの主キー (テーブルに主キーがある場合) の一部またはすべてが含まれている必要があります。パーティション キーとして列名が指定されていない場合は、テーブルの主キー (存在する場合) が使用されます。たとえば、次の CREATE TABLE ステートメントは MySQL 8.0 で有効です。

例 1:

CREATE TABLE k1 (
    id INT NOT NULL PRIMARY KEY,
    name VARCHAR(20)
)
PARTITION BY KEY() -- 注意这里的key()没有指定列,则默认是按主键分区
PARTITIONS 2;

例 2:

CREATE TABLE tm1 (
    s1 CHAR(32) PRIMARY KEY
)
PARTITION BY KEY(s1)
PARTITIONS 10;

2.5. COLUMNS パーティション

公式サイトアドレス: RANGE COLUMNS パーティショニング/ LIST COLUMNS パーティショニング
COLUMNS パーティショニングは MYSQL5.5 で導入されたパーティション タイプです. COLUMNS パーティショニングの導入の目的は、MYSQL5.5 より前のバージョンの RANGE パーティショニングと LIST パーティショニングが整数パーティショニングのみをサポートしているという問題を解決することです, これには、追加の関数計算の結果が整数になるか、追加の変換テーブルがそれらをパーティション内の整数に変換する必要があります。COLUMNS パーティションは、RANGE COLUMNS パーティションと LIST COLUMNS パーティションにさらに分割できます。どちらも、整数、日付、文字列の 3 つの主要なデータ型をサポートしています。

  • すべての整数型: tinyint、smallint、mediumint、int (Integer)、bigint、Decimal や Float などの他の数値型はサポートされていません。
  • 日付と時刻のタイプ: 日付、日時
  • 文字型: char、varchar、binary、varbinary、text および blob 型はパーティション キーとしてサポートされません。
    注: COLUMNS パーティションは、パーティション キーとして 1 つ以上のフィールド名のみをサポートし、パーティション キーとしての式をサポートしません。(RANGE パーティショニングや LIST パーティショニングとは異なります)、複数の列の RANGE COLUMNS パーティショニングを次のように使用します。

2.5.1、範囲列

RANGE COLUMNS パーティションは、次の点で RANGE パーティションと大きく異なります。

  • RANGE COLUMNS は式を受け入れず、列名のみを受け入れます。
  • RANGE COLUMNS は 1 つ以上の列のリストを受け入れます。

文法:

CREATE TABLE table_name
PARTITION BY RANGE COLUMNS(column_list) (
    PARTITION partition_name VALUES LESS THAN (value_list)[,
    PARTITION partition_name VALUES LESS THAN (value_list)][,
    ...]
)

column_list:
    column_name[, column_name][, ...]

value_list:
    value[, value][, ...]

例 1:

CREATE TABLE rcx (
    a INT,
    b INT,
    c CHAR(3),
    d INT
)
PARTITION BY RANGE COLUMNS(a,d,c) (
    PARTITION p0 VALUES LESS THAN (5,10,'ggg'),
    PARTITION p1 VALUES LESS THAN (10,20,'mmm'),
    PARTITION p2 VALUES LESS THAN (15,30,'sss'),
    PARTITION p3 VALUES LESS THAN (MAXVALUE,MAXVALUE,MAXVALUE)
);

例 2:

-- 对日期类型的分区,不再需要year()函数了,而直接使用columns
create table t_columns(
a int,
b datetime
)engine=innodb
partition by range columns (b) (
partition p0 values less than ('2009-01-01'),
partition p1 values less than ('2010-01-01')
);

-- 可以直接使用字符串的分区
create table t_columns2(
a int,
b datetime,
city varchar(15)
)engine=innodb
partition by list columns(city) (
partition p1 values in ('a','b','c'),
partition p2 values in ('d','e','f'),
partition p3 values in ('g','h','k'),
);

-- 可以使用多个列进行分区:
create table rcx (
a int,
b int,
c char(3)
)engine=innodb
partition by range columns(a,b,c) (
partition p0 values 
);

3. パーティションフィールドと主キー

MYSQL のパーティション フィールドは、主キー フィールドまたは一意のインデックス列に含まれている必要があります。テーブルに主キーまたは一意のインデックス列がある場合は、パーティション化フィールドが主キーまたは一意のインデックス列に含まれている必要があります。つまり、すべてのパーティション化フィールドが主キーまたは一意のインデックス列の一部またはすべてに属している必要があります。非主キーおよび非一意の列ではインデックスを作成できません。列フィールドはパーティション フィールドとして機能します。もちろん、主キーのないテーブルのパーティションを作成することもできます。

テーブルをパーティション分割するときに、パーティション フィールドが主キー フィールドに含まれていない場合、エラーが直接報告されます。

テーブルの主キーが id で、日付フィールドをパーティション フィールドとして使用するとします。この場合、日付フィールドは主キーの一部として使用する必要があります。() を組み合わせた主キーを作成できます。 id、date)、そうでない場合は、パーティションの作成時にエラーが直接報告されます。

4. パーティションの使用

4.1. データベースがパーティショニングをサポートしているかどうかを問い合わせる

パーティショニング機能はMySQL 5.1から導入されており、サポートされているかどうかは以下で確認できます。

古いバージョン (5.6 より前):

SHOW VARIABLES LIKE '%partition%';

出力: have_partitioning YES の場合、パーティショニングがサポートされており、デフォルトで有効になっていることを意味します。
ここに画像の説明を挿入します

新しいバージョン (5.6 以降):

show plugins;

すべてのプラグインを表示します。パーティション - ACTIVE - STORAGE ENGINE - GPL プラグインがある場合は、パーティショニングがサポートされていることを示します。
ここに画像の説明を挿入します

mysql8.0 SHOW PLUGINS 命令输出以及 INFORMATION_SCHEMA.PLUGINS 表不再显示 partition。

4.2. パーティションの作成

create table if not exists product
(
	id int not null ,
	name varchar(20) null comment '商品名称',
	type varchar(20) not null comment '商品类型',
    primary key(id,type)
) partition by key(type) partitions 4;  -- 根据商品类型进行分区,创建4个分区


insert into product values
(1,'格力空调','空调'),
(2,'美的空调','空调'),
(3,'九阳电饭煲','电饭煲'),
(4,'苏泊尔电饭煲','电饭煲'),
(5,'小米手机','手机'),
(6,'华为手机','手机');

パーティションを作成するときに、パーティションの数だけを指定し、パーティション名を指定しない場合、パーティション名はデフォルトで 0 から始まり、p0、p1、p2... となります。
ここに画像の説明を挿入します

4.3. パーティションを作成し、パーティション名を指定します

create table if not exists tt
(
	id int not null primary key,
   name varchar(20) null comment '商品名称'
)engine=InnoDB partition by hash(id) partitions 3 (partition t1,partition t2,partition t3);

ここに画像の説明を挿入します

4.4. スキーマ内のどのテーブルがパーティションテーブルであるか/各テーブルにあるパーティションの数/使用されているパーティションの数/パーティション名/各パーティションのデータ量を確認する

select * 
FROM information_schema.PARTITIONS 
WHERE TABLE_SCHEMA=SCHEMA();

或者

select * 
FROM information_schema.PARTITIONS 
WHERE TABLE_SCHEMA='your schema name';

実行 SQL インターセプト部の内容は次のとおりです。
ここに画像の説明を挿入します
上の図では、スキーマ テストを使用してライブラリ内のすべてのテーブルの情報を確認できます: パーティション化するかどうか、パーティション名、パーティション数、パーティション タイプ (リスト、範囲、キー、ハッシュ)、パーティション フィールド、各パーティション内のデータ量など。

上記の SQL は、パーティション テーブルの情報だけでなく、テストするスキーマが設定されたライブラリ内のすべてのテーブルの情報をクエリします。もちろん、次のように、パーティション テーブルの情報のみをクエリするように SQL ステートメントを変更することもできます。詳細については、公式
ここに画像の説明を挿入します
注意:information_schema.partitions对于InnoDB表,table_rows行计数仅是大概估计值,不准确。所以有时候可能会有误差仅作为参考
Web サイトのINFORMATION_SCHEMA PARTITIONS テーブルを参照してください。

4.5. テーブルがパーティションテーブルであるかどうかのクエリ

方法 1: show create table コマンドを使用して ddl ステートメントを表示する
以下に示すように、表示された ddl ステートメントから、テーブルがパーティション テーブルであることがわかります。

mysql> show create table product;
ERROR 2013 (HY000): Lost connection to MySQL server during query
No connection. Trying to reconnect...
Connection id:    58
Current database: test

+---------+-----------------------------------------------------------------------------------------+
| Table   | Create Table

                                                                    |
+---------+-----------------------------------------------------------------------------------------+
| product | CREATE TABLE `product` (
  `id` int NOT NULL,
  `name` varchar(20) DEFAULT NULL COMMENT '商品名称',
  `type` varchar(20) NOT NULL COMMENT '商品类型',
  PRIMARY KEY (`id`,`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
/*!50100 PARTITION BY KEY (`type`)
PARTITIONS 4 */ |
+---------+-----------------------------------------------------------------------------------------+
1 row in set (0.04 sec)

方法 2: information_schema.PARTITIONS をクエリしてパーティションの詳細を取得する

select PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION,PARTITION_DESCRIPTION,TABLE_ROWS
FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA='test' AND TABLE_NAME='product';

ここに画像の説明を挿入します

4.6. 指定されたパーティション内のデータをクエリする

以下の図から、products テーブルのデータはすべて p2 および p3 パーティションにあることがわかります。
ここに画像の説明を挿入します
単一のパーティション内のデータをクエリします。

select * from product partition (p2) ;

ここに画像の説明を挿入します
mysql5.5.41 は指定されたパーティションに対するクエリをサポートしていないことに注意してください。5.6 では、指定されたパーティションに対するクエリのサポートを含め、パーティション化されたテーブルのパーティションに対する関連操作が強化されました。

複数のパーティション内のデータをクエリする

select * from product partition (p2,p3) ;

ここに画像の説明を挿入します
パーティションとクエリを組み合わせた場所

select * from product partition (p2,p3)  where id in (1,6);

ここに画像の説明を挿入します
パーティションのあるテーブルの場合、クエリ データはデフォルトでパーティションごとに並べ替えられます。

CREATE TABLE `person` (
     `id` INT,
     `name` VARCHAR(50),
     `birthday` DATE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY RANGE( YEAR(birthday) ) (
     PARTITION p0 VALUES LESS THAN (1990),
     PARTITION p1 VALUES LESS THAN (1995),
     PARTITION p2 VALUES LESS THAN (2000)
);

INSERT INTO person VALUES
(1, 'lava', '1998-12-25'),
(2, 'admin', '1993-11-05'),
(3, '张三', '1996-03-10'),
(4, '李四', '1982-01-10'),
(5, '王五', '1984-09-16'),
(6, '赵六', '1987-06-05'),
(7, 'tony', '1992-08-04');

以下に示すように: id=4,5,6 は p0 パーティション、id=2,7 は p1 パーティション、id=1,3 は p2 パーティションです。
ここに画像の説明を挿入します

4.7. パーティションの追加

-- range/list参考
alter table person add partition(PARTITION p6 VALUES LESS THAN (2020));

-- key/hash参考
alter table product add partition(PARTITION p6);
或者
alter table product add partition partitions 2;

注意:

  1. 削除できるのはレンジ パーティションとリスト パーティションのみですが、キー パーティションとハッシュ パーティションは削除できません。キー/ハッシュ パーティションを追加する場合は注意してください。
  2. キー/ハッシュ パーティションの場合、新しいパーティションを追加すると、前のテーブルのデータが再パーティション化されます。
  3. RANGE パーティション テーブルの場合、新しいパーティションはパーティション リストの先頭にのみ追加できます。
  4. LIST パーティション化されたテーブルの場合、パーティション値の既存のリストにすでに含まれている値を追加することはできません。

ケース 1: 範囲タイプごとにパーティションを追加する

CREATE TABLE `person` (
     `id` INT,
     `name` VARCHAR(50),
     `birthday` DATE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY RANGE( YEAR(birthday) ) (
     PARTITION p0 VALUES LESS THAN (1990),
     PARTITION p1 VALUES LESS THAN (1995),
     PARTITION p2 VALUES LESS THAN (2000)
);

INSERT INTO person VALUES
(1, 'lava', '1998-12-25'),
(2, 'admin', '1993-11-05'),
(3, '张三', '1996-03-10'),
(4, '李四', '1982-01-10'),
(5, '王五', '1984-09-16'),
(6, '赵六', '1987-06-05'),
(7, 'tony', '1992-08-04');
-- 新增分区   新增的分区数值只能比之前的更大
alter table person add partition (PARTITION p3 VALUES LESS THAN (2005));

4.8. パーティションの削除

注意:
1.只支持删除range、 list分区 ,不支持删除key、 hash分区
2.删除分区后,分区内的数据也会被删除

# list/range删除分区
alter table person drop partition p3;

# key/hash不能通过drop删除分区,可以通过coalesce减少分区
语法:ALTER TABLE table_name COALESCE PARTITION num
示例:alter table product coalesce partition 2; -- 将原来的分区减少两个

4.9. パーティションデータのクリア

# 清空某分区的数据
alter table person truncate partition p0;

4.10. すべてのパーティションを削除しますが、データは保持します

パーティション化されたテーブルを非パーティション化テーブルに変換する場合は、すべてのパーティションを削除できます。

# 格式
ALTER TABLE table_name remove partitioning;

# 样例
alter table person remove partitioning;

4.11. パーティションの再定義 (パーティションの分割、パーティションのマージ、名前の変更)

データを失わずにパーティションを再定義したい場合は、次のステートメントを使用できます。

# 格式  range/list
alter table tbl_name reorganize partition partition_list into(partition_definitions)

# key/hash不能通过REORGANIZE合并分区,可以通过coalesce减少分区,达到合并分区的效果
语法:ALTER TABLE table_name COALESCE PARTITION num
示例:alter table product coalesce partition 2; -- 将原来的分区减少两个

# 样例:range/list  合并分区
ALTER TABLE tbl_name REORGANIZE PARTITION s0,s1 INTO(partition p0 values in(1,2,3,4,5));

#样例:range/list  拆分分区
alter table person reorganize partition p0,p1 into(partition s0 values less than(5),partition s1 values less than(10));
或者如:
alter table tbl_name reorganize partition p0 into(partition s0 values in(1,2,3), partition s1 values in(4,5));

注: パーティションを分割する場合は、パーティション内のすべてのデータを分割する必要があります。
のように:

CREATE TABLE `person` (
     `id` INT,
     `name` VARCHAR(50),
     `birthday` DATE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY RANGE( YEAR(birthday) ) (
     PARTITION p0 VALUES LESS THAN (2005)
);
alter table person reorganize partition p0 into(
	partition s0 values less than(1995),
	partition s1 values less than(2005) --这里的数值必须跟p0分区的数值一致或者更大
);

4.12. クエリ時に使用されるパーティション

クエリがパーティション テーブルに基づいている場合、クエリがアクセスするパーティションが表示されます。5.7 より前のバージョンでは、パーティションを表示するには Explain Partitions コマンドを使用する必要があり、フィルタリングして表示するには Explain Extended コマンドを使用する必要があります。バージョン 5.7 以降では、Explain はデフォルトでパーティション内の情報を直接表示し、フィルター処理されます。

explain select * from product where type ='手机';

ここに画像の説明を挿入します

4.13. その他のパーティション管理ステートメント

1. パーティションを再構築します。パーティションに保存されているすべてのレコードを最初に削除してから再挿入するのと同様に、パーティションの最適化に使用できます。例: ALTER table tbl_name REBUILD PARTITION p2,p3;

2. パーティション分割の最適化: パーティションから多数の行が削除された場合、または可変長の行に多くの変更が加えられた場合 (つまり、VARCHAR、BLOB、または TEXT タイプの列がある場合)、ALTER TABLE tbl_name を使用できます。 OPTIMIZE PARTITION を使用して、未使用の領域を再利用し、パーティション データ ファイルを最適化します。例: ALTER TABLE tbl_name OPTIMIZE PARTITION p2,p3;

mysql8.0 以降、ALTER TABLE … OPTIMIZE PARTITION ステートメントは InnoDB パーティション テーブルに対して有効ではなくなりました。代わりに次のステートメントを使用してください:
ALTER TABLE … REBUILD PARTITION
ALTER TABLE … ANALYZE PARTITION

3. パーティションを分析します。次のように、パーティションのキー配布を読み取り、保存します。 ALTER TABLE tbl_name ANALYZE PARTITION p2,p3;

4. パーティションを確認します。次のように、パーティション内のデータまたはインデックスが破損していないか確認します。 ALTER TABLE tbl_name CHECK PARTITION p2, p3;

5. パーティションを修復します: ALTER TABLE tbl_name REPAIR PARTITION p2, p3; のように、破損したパーティションを修復します。

5. パーティション使用時に発生する可能性のある問題

5.1、[HY000][1493] VALUES LESS THAN 値はパーティションごとに厳密に増加する必要があります

エラー内容は以下の通りです。

[HY000][1493] VALUES LESS THAN value must be strictly increasing for each partition

翻訳: [HY000][1493] 各パーティションについて、その値未満の値は厳密に増やす必要があります

エラー シナリオ:
新しいパーティションを範囲パーティションに追加するとき、値が以前の最小値より小さくなります。次のように: 1995 ~ 2000 の間に別のパーティションを追加したい場合、このエラーが報告されます。追加されるパーティションは 2000 より大きい必要があります。

CREATE TABLE `person` (
     `id` INT,
     `name` VARCHAR(50),
     `birthday` DATE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY RANGE( YEAR(birthday) ) (
     PARTITION p0 VALUES LESS THAN (1990),
     PARTITION p1 VALUES LESS THAN (1995),
     PARTITION p2 VALUES LESS THAN (2000)
);

mysql> alter table person add partition (PARTITION p3 VALUES LESS THAN (1998));
[HY000][1493] VALUES LESS THAN value must be strictly increasing for each partition

5.2、エラー 1512 (HY000): DROP PARTITION は RANGE/LIST パーティションでのみ使用できます

キーおよびハッシュパーティションテーブルの削除はサポートされていません

create table if not exists product
(
	id int not null ,
	name varchar(20) null comment '商品名称',
	type varchar(20) not null comment '商品类型',
    primary key(id,type)
) partition by key(type) partitions 4; 

mysql> alter table product drop partition p1;
ERROR 1512 (HY000): DROP PARTITION can only be used on RANGE/LIST partitions

ERROR 1512 (HY000): DROP PARTITION can only be used on RANGE/LIST partitions

参考記事:
https://www.cnblogs.com/wenxuehai/p/15901779.html#_label2_1公式
サイトパーティショニング https://dev.mysql.com/doc/refman/8.0/en/partitioning.html
公式でのパーティショニングの説明公式サイト とても詳しくて見やすく、詳しく知りたい方は公式サイトで答えを見つけることができます。

おすすめ

転載: blog.csdn.net/weixin_49114503/article/details/132050910