分区表是一个独立的逻辑表,但是底层是由多个物理子表组成,MySQL实现分区表的方式,是对底层表的封装,意味着索引也是按照分区的子表定义的,而没有全局索引。所以分区表可以看成合并表的升级,是做了性能优化的智能化的分表,不能单独操作子表。

MySQL在创建表时使用PARTITION BY子句定义每个分区存放的数据。在执行查询时,优化器会根据分区定义过滤那些没有用到的分区,这样查询就无须扫描所有分区,而只需查找包含需要数据的分区就可以了。

分区表的创建语法如下:

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name(create_definition,...)[table_options][partition_options]partition_options:PARTITION BY{ [LINEAR] HASH(expr)| [LINEAR] KEY [ALGORITHM={1|2}] (column_list)| RANGE{(expr) | COLUMNS(column_list)}| LIST{(expr) | COLUMNS(column_list)} }[PARTITIONS num][SUBPARTITION BY{ [LINEAR] HASH(expr)| [LINEAR] KEY [ALGORITHM={1|2}] (column_list) }[SUBPARTITIONS num]][(partition_definition [, partition_definition] ...)]partition_definition:PARTITION partition_name[VALUES{LESS THAN {(expr | value_list) | MAXVALUE}|IN (value_list)}][[STORAGE] ENGINE [=] engine_name][COMMENT [=] 'string' ][DATA DIRECTORY [=] 'data_dir'][INDEX DIRECTORY [=] 'index_dir'][MAX_ROWS [=] max_number_of_rows][MIN_ROWS [=] min_number_of_rows][TABLESPACE [=] tablespace_name][(subpartition_definition [, subpartition_definition] ...)]subpartition_definition:SUBPARTITION logical_name[[STORAGE] ENGINE [=] engine_name][COMMENT [=] 'string' ][DATA DIRECTORY [=] 'data_dir'][INDEX DIRECTORY [=] 'index_dir'][MAX_ROWS [=] max_number_of_rows][MIN_ROWS [=] min_number_of_rows][TABLESPACE [=] tablespace_name]

详情请参考官方文档:从中可以看出,可以指定单个分区的存储引擎和存储路径。

一、分区表的优点

  1. 相对合并表而言,分区表的数据更容易维护。
  2. 批量删除特别方便,特别是需要删除整个分区的数据时。
  3. 分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备。
  4. 分区表对查询性能进行了优化,通过在查询条件中指定分区键的区域限制来实现。
  5. 5.7以后可以通过在WHERE后面指定查询分区来指定在哪个分区中查询数据。例如:SELECT * FROM t PARTITION (p0,p1) WHERE c < 5
  6. 可以使用分区表来避免某些特殊瓶颈,例如InnoDB的单个索引的互斥访问,ext3文件系统的inode锁竞争(好像现在的linux系统使用ext4的比较多)。
  7. 可以备份和恢复独立的分区,这在非常大的数据集中。
  8. 分区表可以使用大多数MySql存储引擎,但是分区表包括底层表必须使用同一种存储引擎,尽管选择比较多,例如InnoDB,MyISAM)。分区不能使用的存储引擎包括:MERGECSV和 FEDERATED。

二、分区表的限制

  1. 分区表达式或者表达式返回值必须是整数,或者可以直接使用列来进行分区。
  2. 若需要在分区表中建立主键或唯一性索引,那么分区字段必须包含每个主键或唯一性索引的全部或部分字段。即每一个唯一性索引都必须由列包含在分区字段中。
  3. 分区表中无法使用外键约束。

三、分区表的使用场景

分区表是为了解决一个数据表中数据量过大,而影响操作性能的一种智能解决方案。以下场景适合使用分区表。

  1. 表非常大以至于无法全部放在内存中,或者热点数据比较集中,而其他数据都是历史数据。

四、分区表的类型

分区表包含的类型有:Range分区、List分区,Columns分区,Hash分区、Key分区和子分区。对于 [LINEARKEYRANGE COLUMNS, 和 LIST COLUMNS,分区表达式中可以包含一个或多个列,对于 [LINEARKEY分区,分区表达式必须是MySql提供的函数。

1、Range分区

Range意为范围、排列。Range分区顾名思义,就是对连续排列的的整数数据或通过函数转换为整数的数据用操作符VALUES LESS THAN进行分区。举例如下:

CREATE TABLE employees (id INT NOT NULL,name VARCHAR(64),job_code INT NOT NULL
)
PARTITION BY RANGE (job_code) (PARTITION p1 VALUES LESS THAN (100),PARTITION p2 VALUES LESS THAN (1000),PARTITION p3 VALUES LESS THAN (10000)
);

为了防止插入的数据的分区表达式的值超出分区定义的范围,MySql提供MAXVALUE表示最大值,-MAXVALUE表示最小值。在最后一个分区的后天添加PARTITION pn VALUES LESS THAN MAXVALUE。

对于分区键可能为空的数据,会插入第一个分区里面。所以若要需要额外存储分区键为NULL的数据,需要在第一个分区前面添加一个有意义值外的分区,例如对于表employees可以在p0前面添加分区p0:PARTITION p0 VALUES LESS THAN (0)。

Range分区的使用场景如下:

a、随着时间的流逝,数据会变得过时,可以批量删除的数据。特别是当你可以一次删除一个分区的时候,可以这样删:ALTER TABLE employees DROP PARTITION p1,比在整个表中删除(delete from employees where job_code < 100)要高效的多。

b、当你根据时间列进行组织数据时,或者按照递增列进行组织数据时。

c、当你需要频繁地需要按一递增列的区间进行查询或统计时。

Range分区的一个变体是RANGE COLUMNS分区。此分区可以根据多个列的值进行分区。详情请参考官方文档。

基于时间间隔的分区有两种选择:

a、若分区字段类型为DATE,TIME或DATETIME,使用能返回整数的时间函数YEAR,MONTH等,如:

CREATE TABLE members (name VARCHAR(64) NOT NULL,joined DATE NOT NULL
)
PARTITION BY RANGE( YEAR(joined) ) (PARTITION p0 VALUES LESS THAN (1980),PARTITION p1 VALUES LESS THAN (1990),PARTITION p2 VALUES LESS THAN (2000),PARTITION p3 VALUES LESS THAN (2010),PARTITION p4 VALUES LESS THAN MAXVALUE
);

若分区键的类型为TIMESTAMP,可以使用函数UNIX_TIMESTAMP,例如:

CREATE TABLE members (name VARCHAR(64) NOT NULL,joined TIMESTAMP NOT NULL
)
PARTITION BY RANGE( UNIX_TIMESTAMP(joined) ) (PARTITION p0 VALUES LESS THAN (UNIX_TIMESTAMP('1980-01-01 00:00:00')),PARTITION p1 VALUES LESS THAN (UNIX_TIMESTAMP('1990-01-01 00:00:00')),PARTITION p2 VALUES LESS THAN (UNIX_TIMESTAMP('2000-01-01 00:00:00')),PARTITION p3 VALUES LESS THAN (UNIX_TIMESTAMP('2010-01-01 00:00:00')),PARTITION p4 VALUES LESS THAN MAXVALUE
);

b、若分区键类型为DATE或DATETIME,还可以使用RANGE COLUMNS分区。如下:

CREATE TABLE members (name VARCHAR(64) NOT NULL,joined DATETIME NOT NULL
)
PARTITION BY RANGE COLUMNS(joined) (PARTITION p0 VALUES LESS THAN ('1980-01-01'),PARTITION p1 VALUES LESS THAN ('1990-01-01'),PARTITION p2 VALUES LESS THAN ('2000-01-01'),PARTITION p3 VALUES LESS THAN ('2010-01-01'),PARTITION p4 VALUES LESS THAN MAXVALUE
);

2、List分区

List分区是按离散值进行分区,这些离散值可能没有顺序,也不连续,并且分区键的每一个值都必须包含在其中一个分区中,否则会报错。定义分区语法如下:

CREATE TABLE employees (id INT NOT NULL,name VARCHAR(64),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)
);

分区键必须是整数值或者返回整数值的函数。

为List分区添加或删除与某个分区相关的数据会很高效。可以通过ALTER TABLE employees TRUNCATE PARTITION pWest或者ALTER TABLE employees DROP PARTITION pWest删除pWest分区里的数据,要比通过DELETE FROM employees WHERE store_id IN (4,12,13,14,18)删除数据高效许多。

List分区罗列了所有的可用来分区的值,若插入的数据不在这些值之中,则会插入失败并报错。若使用一个insert语句批量插入数据,对于数据表的存储引擎为事务性的情况,例如InnoDB,则全部插入失败;对于数据表的存储引擎为非事务性的情况,例如MyISAM,则错误之前的数据可以插入,错误之后的数据则插入失败。若可以忽略这种情况,则可以使用INSERT IGNORE INTO来忽略插入错误的数据,不影响其他正确数据的插入。

与Range分区一样,List分区也有List Columns变体,支持按一个或多个字段分区,且不要求必须是整数类型。

3、Columns分区

前面已经提过,Columns分区包括Range Columns分区和List Columns分区。Columns分区允许一个或多个列作为分区键且不要求分区键中的列类型为整数,所以大大提高了分区键的选择性。允许作为Columns分区键的列的数据类型如下:

  • 所有整数: TINYINT, SMALLINT, MEDIUMINT, INT (INTEGER)和 BIGINT
  • DATE和DATETIME
  • 字符类型: CHAR, VARCHAR, BINARY, 和VARBINARY。

3.1、Range Columns分区

Range Columns分区的语法如下:

CREATE TABLE table_name
PARTITIONED 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][, ...]

Range Columns分区与Range 分区在以下方面有显著区别:

  • Range Columns不接受表达式,仅接受列名称。
  • Range Columns接受一列或多列,若按多列分区,则多列组成一个元组(Python中有此数据结构),元组中列的位置与数据表中的列位置无关,但比较值中的列的位置必须一致,比较时是按元组比较大小,而不是按标量比较大小:即先比较第一列,只有在第一列值相同的前提下才比较第二列,以此类推。
  • Range Columns分区的列不限于整数列,这在前面也已说明。

3.2、List Columns分区

List Columns分区的特点与用法与Range Columns分区一致,此处不再累述。

4、Hash分区

Hash分区主要用来确保把数据均匀分配到指定数量的分区中。使用Range分区和List分区,你能明确知道每一个数据应该存储在哪个分区中,而使用Hash分区,MySql帮你确认应该把数据存储在哪个分区中。你仅指定用来分区的列、表达式以及分区的数量。例如:

CREATE TABLE employees (id INT NOT NULL,name VARCHAR(64),store_id INT
)
PARTITION BY HASH(store_id)
PARTITIONS 4;

分区键包含的列类型应为整数或返回整数的表达式。表达式不可以返回常量或者随机数。分区键插入的值不变,Hash函数返回的值也应不变。高效的Hash函数是返回的值随着列的值的增减而作线性变化。

当使用PARTITION BY HASH时,MySQL根据分区表达式的返回值的模数来决定数据存放在num个分区中的第几个分区里。若存放的分区为N那么N=MOD(expr,num)。例如分区表t1:

CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE)PARTITION BY HASH( YEAR(col3) )PARTITIONS 4;

那么若插入的数据中col3为'2015-09-01',数据应该存储的区域的计算公式为:MOD(YEAR('2005-09-01'),4) =  MOD(2005,4) =  1。

MySql5.7还支持Hash分区的另一个变体LINEAR HASH分区,其使用了更复杂的算法,后面会介绍。

4.1、LINEAR HASH分区

MySql也支持Linear Hash分区,与常规hash算法不同,Linear Hash分区使用了一种线性为2的幂的算法。而常规Hash算法采用Hash函数值的模。在语法上,Linear Hash 分区只是在原来的基础上多了Linear关键字。如下:

CREATE TABLE employees (id INT NOT NULL,name VARCHAR(64),hired DATE NOT NULL DEFAULT '1970-01-01'
)
PARTITION BY LINEAR HASH( YEAR(hired) )
PARTITIONS 4;

Linear Hash算法如下:若表达式为expr,分区数为num,插入数据的最终分区为N,假设一个比num大的2的幂值为V,那么

V = POWER(2, CEILING(LOG(2, num)))

N = expr & (V - 1)

若 N > num,则:

V = V / 2

N = N & (V - 1)

Linear Hash分区的优点是处理超大数据(TB级)的数据表时,对分区表的添加、删除,合并和切分都是非常快的;缺点是相对Hash 分区来说,数据在分区中的分布不够均匀。

5、Key分区

Key分区与Hash分区相似,只是Hash分区使用用户定义的表达式,而Key分区使用MySQL提供的Hash函数。NDB集群使用MD5也是基于此目的;对于使用其他存储引擎的数据表,服务器使用其内部的基于相同算法的Hash函数,例如:PASSWORD()。

Key分区与Hash分区的语法类似:CREATE TABLE ... PARTITION BY KEY。它们的主要区别如下:

  • 用KEY关键字替换HASH关键字,并且HKEY()中可以不指定分区键。
  • KEY后面仅使用一个或多个列名列表,不使用表达式。
  • 若表中有主键,分区键必须是组成主键列的一部分。若不指定分区键,就默认使用主键列。若没有主键而有唯一性键,也同样。例如:
    CREATE TABLE k1 (id INT NOT NULL PRIMARY KEY,name VARCHAR(20)
    )
    PARTITION BY KEY()
    PARTITIONS 2;

    但是,若唯一性键的列没有设置为NOT NULL,则前面的例子就是失败的。

与其他分区类别不同的是,用来作为KEY分区的列不要求是整数类型或NULL值。Key分区也有变体Linear Key分区。使用的算法与Linear Hash分区的算法相似,此处不再累述。KEY 和 LINEAR KEY 分区可以使用NDB,而其他分区的不可以,详情参考MySql官方文档。

6、子分区

子分区又叫组合分区,是对分区表中的分区的进一步分区。创建子分区的语法如下:

CREATE TABLE ts (id INT, purchased DATE)PARTITION BY RANGE( YEAR(purchased) )SUBPARTITION BY HASH( TO_DAYS(purchased) )SUBPARTITIONS 2 (PARTITION p0 VALUES LESS THAN (1990),PARTITION p1 VALUES LESS THAN (2000),PARTITION p2 VALUES LESS THAN MAXVALUE);

在MySql5.7中,可以对Range分区和List分区再进一步分区,子分区可以使用Hash分区和Key分区,所以才叫组合分区。创建子分区时,也可以通过使用SUBPARTITION 语句定义每个子分区的选项。如下:


CREATE TABLE ts (id INT, purchased DATE)PARTITION BY RANGE( YEAR(purchased) )SUBPARTITION BY HASH( TO_DAYS(purchased) ) (PARTITION p0 VALUES LESS THAN (1990) (SUBPARTITION s0,SUBPARTITION s1),PARTITION p1 VALUES LESS THAN (2000) (SUBPARTITION s2,SUBPARTITION s3),PARTITION p2 VALUES LESS THAN MAXVALUE (SUBPARTITION s4,SUBPARTITION s5));

使用子分区时,在语法上的注意事项如下:

  • 每一个分区必须由相同数量的子分区;
  • 如果要通过SUBPARTITION 明确定义分区表的分区的子分区,则必须定义每个分区的子分区,不可仅定义部分分区的子分区。
  • 每个SUBPARTITION 语句必须至少包含子分区名称,否则,你就是允许使用系统默认设定的名字。
  • 子分区的名称在整个表中必须是唯一的。

使用MyISAM存储引擎的分区表,可以分别指定每个子分区数据和索引存储的位置,包括跨多硬盘存储。例如:

CREATE TABLE ts (id INT, purchased DATE)ENGINE = MYISAMPARTITION BY RANGE( YEAR(purchased) )SUBPARTITION BY HASH( TO_DAYS(purchased) ) (PARTITION p0 VALUES LESS THAN (1990) (SUBPARTITION s0DATA DIRECTORY = '/disk0/data'INDEX DIRECTORY = '/disk0/idx',SUBPARTITION s1DATA DIRECTORY = '/disk1/data'INDEX DIRECTORY = '/disk1/idx'),PARTITION p1 VALUES LESS THAN (2000) (SUBPARTITION s2DATA DIRECTORY = '/disk2/data'INDEX DIRECTORY = '/disk2/idx',SUBPARTITION s3DATA DIRECTORY = '/disk3/data'INDEX DIRECTORY = '/disk3/idx'),PARTITION p2 VALUES LESS THAN MAXVALUE (SUBPARTITION s4DATA DIRECTORY = '/disk4/data'INDEX DIRECTORY = '/disk4/idx',SUBPARTITION s5DATA DIRECTORY = '/disk5/data'INDEX DIRECTORY = '/disk5/idx'));

若MySql设置为NO_DIR_IN_CREATE模式,则DATA DIRECTORY 和 INDEX DIRECTORY是不允许设置的。

7、MySql分区如何处理NULL

MySql分区没有限制NULL值做分区表达式的值,而是当需要排序时把NULL当初小于任何一个NON-NULL值的值。但每一种分区对NULL的处理是不同的。若不注意对NULL的处理,会造成你意料之外的情况。

  • Range分区对NULL的处理。如果你向一个Range分区表里插入一行数据,作为分区键的列的值为NULL,则数据插入到第一个分区里。
  • List分区对NULL的处理。List分区表允许NULL作为其中一个(只能一个)分区中的列表的一项值。若在定义分区表时没有考虑NULL值的情况,则不允许作为分区键的列值为NULL的数据插入。
  • Hash分区和Key分区对NULL的处理。Hash或Key分区表对NULL的处理有些不同。在这种情况下,任何返回NULL的分区表达式,都被当成好像返回0一样处理。

五、管理分区表

MySQL5.7提供很多方法修改分区表。包括新增、删除、重定义、合并和拆分已存在的分区表。所有这些操作都通过ALTER TABLE语句的扩展来实现。仅通过ALTER TABLE tablename partition_options 就可以修改一个表的分区方案(即:修改分区类型),其中partition_options 与创建分区表中一样。ALTER TABLE 后面只能跟一个修改语句(PARTITION BYADD PARTITIONDROP PARTITIONREORGANIZE PARTITION, 或 COALESCE PARTITION),不可联合使用。要删除一个分区里的数据,需要执行语句: ALTER TABLE ... TRUNCATE PARTITION。

1、管理Range分区和List分区。

对Range分区和List分区来说,新增和删除分区是一样的形式,所以在此一起介绍。删除分区的语法如下:

ALTER TABLE table_nameDROP PARTITION partition_name;

删除一个分区时,分区内的数据也一同被删除。如果要想在保留数据的前提下删除数据,就需要使用重组分区语句:ALTER TABLE ... REORGANIZE PARTITION。

查询一个分区里的数据,可以通过分区键的过滤条件来查,也可通过制定分区名称来查,例如:

SELECT * FROM table_name PARTITION (partition_name);

新增分区的语法是:

 ALTER TABLE table_name ADD PARTITION partition_name

对于Range分区,只能在最后添加分区。若想在中间或前面添加分区,就需要使用重组分区的语法。把其中一个分区分成多个分区,并且分区必须是连续的,不可有重叠或跨越。例如:

ALTER TABLE table_nameREORGANIZE PARTITION p1 INTO (PARTITION n0 VALUES LESS THAN (value1),PARTITION n1 VALUES LESS THAN (value2)
);

对于List分区,新增的分区不能包括当前已存在的分区键值。若想重组已有分区或新增列举值再重新分区,也需要使用重组分区语法,例如:

/*原分区表结构*/
CREATE TABLE tt (id INT,data INT
)
PARTITION BY LIST(data) (PARTITION p0 VALUES IN (5, 10, 15),PARTITION p1 VALUES IN (6, 12, 18)
);
/*新增分区*/
ALTER TABLE tt ADD PARTITION (PARTITION np VALUES IN (4, 8));
/*重组分区*/
ALTER TABLE tt REORGANIZE PARTITION p1,np INTO (PARTITION p1 VALUES IN (6, 18),PARTITION np VALUES in (4, 8, 12)
);

重组分区可以把一个分区拆分成几个分区,也可以把多个分区合并成一个分区,甚至把n个分区重组为m个分区。语法如下:

ALTER TABLE table_nameREORGANIZE PARTITION partition_listINTO (partition_definitions);

2、Hash分区和Key分区的管理

Hash分区与Key分区的管理方式相同,而与Range分区及List分区的管理差别很大。删除分区的方式与Rang分区及List分区的方式相同,而合并分区的语法则为: ALTER TABLE table_name COALESCE PARTITION n。例如对于Hash分区表:

CREATE TABLE clients (id INT,name VARCHAR(64),signed DATE
)
PARTITION BY HASH( MONTH(signed) )
PARTITIONS 12;

若要从12个分区缩减为8个分区,执行操作如下:

ALTER TABLE clients COALESCE PARTITION 4;

其中4是减少的分区数,所以减少的分区数不可大于分区总数。若要增加分区数,例如从12个分区增加到18个分区,执行如下操作:

ALTER TABLE clients ADD PARTITION PARTITIONS 6;

3、交换表之间分区或子分区(里的数据)。

在MySql5.7中,可以通过语法  ALTER TABLE pt EXCHANGE PARTITION pWITH TABLE nt交换一个表分区或分区与另一个表中的数据。其中pt是分区表,p为pt中的一个分区或子分区,nt为未分区的普通表。对于非分区表的nt,还有以下要求:

  • nt不能分区;
  • nt不能是临时表;
  • nt的表结构与pt的一样,包括:列的数量、顺序、名称、类型和索引,也必须使用同样的存储引擎;
  • nt不能与其他表有外键关系;
  • nt中的数据不能超出p的分区键范围;
  • 两个表的数据引擎若为InnoDB,那么两个表的行格式化方式必须相同。通过查询INFORMATION_SCHEMA.INNODB_SYS_TABLES确认格式化方式。
  • nt没有任何分区使用DATA DIRECTORY选项,此限制在MySql5.7.25以及以后被取消。

执行ALTER TABLE pt EXCHANGE PARTITION pWITH TABLE nt语句的影响如下:

  • 不会调用两个被交换表的任何触发器。
  • 数据交换过程中,所有AUTO_INCREMENT列都会被重置。
  • 在此语句中IGNORE关键字无效。

默认情况下,交换数据会逐行验证数据的合法性,若添加选项 WITHOUT VALIDATION 则忽略验证,以提高交换效率,语法如下:ALTER TABLE pt EXCHANGE PARTITION p WITH TABLE nt WITH VALIDATION,只是数据库管理员要对数据合法性负责任。若真出现不匹配的数据,DBA可以通过以下语句解决: REPAIR TABLE or ALTER TABLE ... REPAIR PARTITION。

交换子分区数据也是同样方式,通过此语句获取子分区名称:

SELECT PARTITION_NAME, SUBPARTITION_NAME, TABLE_ROWSFROM INFORMATION_SCHEMA.PARTITIONSWHERE TABLE_NAME = 'pt';

4、分区维护

在MySql5.7.2以后才支持分区维护功能。表的维护语句也适用于分区表:CHECK TABLE, OPTIMIZE TABLE, ANALYZE TABLE, and REPAIR TABLE。分区的维护与此类似,同样使用ALTER TABLE的扩展来实现。

  • 重建分区: 与删除分区里的数据然后重新插入是一样的,目的是碎片整理,语法如下:

    ALTER TABLE t1 REBUILD PARTITION p0, p1;
  • 优化分区:如果删除了分区里的大类数据或更新了分区里的大量数据,则通过优化分区来回收未被使用的空间及碎片整理,等价于执行了CHECK PARTITION, ANALYZE PARTITION, 和 REPAIR PARTITION,优化分区语法为:

    ALTER TABLE t1 OPTIMIZE PARTITION p0, p1;

    有些存储引擎(包括InnoDB)在同时优化所有分区时,会报异常,可通过 REBUILD PARTITION和ANALYZE PARTITION来替代。

  • 分析分区:读取和存储分区的键分布。语法如下:

    ALTER TABLE t1 ANALYZE PARTITION p3;
  • 修复分区:修复崩溃的分区。若分区中有重复的主键或唯一性键,则修复失败,这时可以使用 ALTER IGNORE TABLE后加修复分区选项。语法如下:

    ALTER TABLE t1 REPAIR PARTITION p0,p1;
  • 检查分区:检查分区中的错误,包括数据和索引崩溃。若分区中有重复的主键或唯一性键,则检查失败,这时可以使用 ALTER IGNORE TABLE后加检查分区选项。语法为:

    ALTER TABLE trb3 CHECK PARTITION p1;

    另外,这些维护语句都支持在PARTITION透明添加ALL来维护所有分区。检查工具 mysqlcheck 和 myisamchk不适用分区表。

六、分区剪切

分区剪切是一种分区优化。其背后的核心理念是很简单的,可以用一句话来描述:不扫描为匹配数据的分区。

只要where条件减少为以下两种情况之一,优化器就执行剪切处理。

1、partition_column = constant。优化器评估哪个分区包含这个值,就只扫描哪个分区。等号还可以延伸为<、>、<=、>=、<>,有些查询中BETWEEN也可以使用剪切。注意constant是常量值。

2、partition_column IN (constant1, constant2, ..., constantN):优化器苹果列表中每个值所在的分区,然后通过仅扫描这些分区来实现剪切效果。

七、显式分区选择

MySQL5.7支持显式分区选择。显式分区选择与分区剪切相似,都只检查扫描匹配的分区,也有不同之处:

  • 显式分区选择是在语句中指定的检查分区,而分区剪切是根据过滤条件自动确定的。
  • 分区剪切只适用于数据查询,而显式分区选择不但适用于数据查询,也适用于许多DML语句。

显式分区选择适用的语句包括:SELECT,DELETE,INSERT,UPDATE,REPLACE,LOAD DATA,LOAD XML。显式分区选择的语法为:

PARTITION (partition_names)partition_names:partition_name, ...

MySql性能优化之分区表相关推荐

  1. 服务器性能优化和Mysql性能优化

    服务器性能优化和Mysql性能优化 影响性能的几个因素 服务器硬件 CPU 内存 IO子系统 服务器系统 CentOS系统参数优化 sysctlconf 优化 limitconf参数优化 磁盘调度策略 ...

  2. 数据库mysql性能优化-学习笔记

    数据库mysql性能优化 1. 数据库设计范式 2. 常见关系数据库 3. MySQL 的版本 4. mysql存储计划 5 . mysql查询配置 和 设置配置 6 . mysql基本参数 7 .m ...

  3. MySQL性能优化:SQL慢查询优化,索引优化,表优化

    1. MySQL优化概述 MySQL 优化是一个综合性的技术,在优化上存在着一个调优金字塔的说法,如下: 很明显从图上可以看出,越往上走,难度越来越高,收益却是越来越小的.比如硬件和 OS 调优,需要 ...

  4. MySQL性能优化总结

    MySQL性能优化总结 影响性能的相关因素 要知道怎么优化MySQL首先要知道什么东西会影响MySQL的效率 商业需求 系统架构 硬件环境 数据库的设计 sql语句 在整个系统的性能优化中,如果按照百 ...

  5. Mysql性能优化方案

    2019独角兽企业重金招聘Python工程师标准>>> 内容简介:这是一篇关于mysql 性能优化的文章.网上有不少mysql 性能优化方案,不过,mysql的优化同sql serv ...

  6. mysql半连接_mysql表的半连接,反连接导致的mysql性能优化剖析

    [导读] 关于Oracle的半连接,反连接,我一直认为这是一个能讲很长时间的话题,所以在我的新书<Oracle DBA工作笔记>中讲性能优化的时候,我花... 关于Oracle的半连接,反 ...

  7. 记一次mysql性能优化过程

    2019独角兽企业重金招聘Python工程师标准>>> 转发自:记一次mysql性能优化过程 由于配置是运行过那么长时间,很稳定,基本上不考虑,所以本次主要是sql的优化,并且集中在 ...

  8. MySQL 性能优化,优化设计及设计原则解读

    MySQL性能优化的目的 如何合理的设计数据库? 什么样的数据库设计才能给后期DBA优化提供基石? 数据库设计与程序设计的差异? 数据库设计早期优化 1. 关系明确(理清表之间的关系,可以通过冗余的方 ...

  9. MySQL性能优化速记

    MySQL性能优化速记http://www.bieryun.com/3064.html 总结自<MySQL 5.7从入门到精通(视频教学版)>刘增杰编著. 优化简介 MySQL数据库优化是 ...

最新文章

  1. arcgis的server不可用
  2. Android架构思考(模块化、多进程)
  3. shell day01 : Shell概述 编写及执行脚本 、 Shell变量
  4. eclipse java8报错_eclipse4.3安装支持Java8插件,之后就报错无法打开eclipse,求解?
  5. 【学习笔记】《数据挖掘:理论与算法》CH4神经网络
  6. Spring加载context的几种方法
  7. Python深入类和对象
  8. jquery.cookie.js操作cookie实现“记住密码”
  9. expr命令 linux,Shell expr命令进行整数计算的实现
  10. Matplotlib - 箱线图、箱型图 boxplot () 所有用法详解
  11. 礼品盒子插画素材丨节日设计加上它之后价值翻倍!
  12. python界面-图形界面
  13. Android -- Camera.ShutterCallback
  14. 发送邮件服务器错误怎么更改,怎么解决SMTP服务器发送邮件失败
  15. cdr添加节点快捷键_cdr快捷键大全_cdr教程【图文】
  16. 一文读懂AB测试原理及样本量计算的Python实现
  17. Docker中文文档 分享
  18. MobaXterm使用技巧
  19. C++11绑定器bind及function机制
  20. 【干货福利】67个拯救web开发者的工具、库和资源!——爱创课堂

热门文章

  1. 计算机清理垃圾文件丢失怎么恢复,如何恢复windows电脑垃圾箱中清除的文件
  2. VMware Workstation 16 Pro启动安装win10 虚拟机蓝屏
  3. 灵魂发问!线程池到底创建多少线程比较合理?
  4. 蓝牙AOA定位网关上报数据格式
  5. dom4j实现XML操作
  6. 【渝粤题库】陕西师范大学202511商法学 作业(高起本)
  7. Markdown 如何让图片居中
  8. JavaScript 基础知识点
  9. java毕业生设计携手同游旅游社交平台计算机源码+系统+mysql+调试部署+lw
  10. Nginx的Https配置及代理api接口配置