与分区相关的子句可以与分区表一起使用,用于重新分区,添加、删除、丢弃、导入、合并和拆分分区,以及执行分区维护。
-
简单地在分区表上使用带有
分区选项子句的修改表语句,根据分区选项定义的分区方案重新分区表。此子句始终以分区依据开头,并遵循与创建表的分区选项子句相同的语法和其他规则(有关更详细的信息,请参阅章节 15.1.20,“创建表语句”),并且还可以用于分区尚未分区的现有表。例如,考虑一个(未分区)表,如下所示:CREATE TABLE t1 ( id INT, year_col INT );可以使用以下语句,通过
哈希将此表分区,使用id列作为分区键,分成8个分区:ALTER TABLE t1 PARTITION BY HASH(id) PARTITIONS 8;MySQL 支持带有
[子]分区依据 [线性] 键的算法选项。算法=1使服务器在计算行在分区中的位置时使用与 MySQL 5.1 相同的键哈希函数;算法=2意味着服务器采用 MySQL 5.5 及更高版本中新键分区表的默认实现和使用的键哈希函数。(使用 MySQL 5.5 及更高版本中采用的键哈希函数创建的分区表不能由 MySQL 5.1 服务器使用。)不指定该选项的效果与使用算法=2相同。此选项主要用于在 MySQL 5.1 和更高版本的 MySQL 版本之间升级或降级[线性] 键分区表,或者用于在 MySQL 5.5 或更高版本的服务器上创建按键或线性键分区并可在 MySQL 5.1 服务器上使用的表。使用
修改表 ... 分区依据语句生成的表必须遵循与使用创建表 ... 分区依据创建的表相同的规则。这包括管理表可能具有的任何唯一键(包括任何主键)与分区表达式中使用的列之间的关系的规则,如章节 26.6.1,“分区键、主键和唯一键”中所述。创建表 ... 分区依据用于指定分区数量的规则也适用于修改表 ... 分区依据。ALTER TABLE ADD PARTITION的partition_definition子句支持与CREATE TABLE语句中同名子句相同的选项。(有关语法和描述,请参见 第 15.1.20 节,“CREATE TABLE 语句”)假设您创建了如下所示的分区表:CREATE TABLE t1 ( id INT, year_col INT ) PARTITION BY RANGE (year_col) ( PARTITION p0 VALUES LESS THAN (1991), PARTITION p1 VALUES LESS THAN (1995), PARTITION p2 VALUES LESS THAN (1999) );您可以向此表添加一个新的分区
p3来存储小于2002的值,如下所示:ALTER TABLE t1 ADD PARTITION (PARTITION p3 VALUES LESS THAN (2002));DROP PARTITION可用于删除一个或多个RANGE或LIST分区。此语句不能与HASH或KEY分区一起使用;而是使用COALESCE PARTITION(请参阅本节后面的内容)。存储在partition_names列表中命名的已删除分区中的任何数据都将被丢弃。例如,对于前面定义的表t1,您可以删除名为p0和p1的分区,如下所示:ALTER TABLE t1 DROP PARTITION p0, p1;NoteDROP PARTITION不适用于使用NDB存储引擎的表。请参阅 第 26.3.1 节,“RANGE 和 LIST 分区的管理”,以及 第 25.2.7 节,“NDB Cluster 的已知限制”。ADD PARTITION和DROP PARTITION目前不支持IF [NOT] EXISTS。DISCARD PARTITION ... TABLESPACE和IMPORT PARTITION ... TABLESPACE选项将 可传输表空间 功能扩展到单个InnoDB表分区。每个InnoDB表分区都有自己的表空间文件(.ibd文件)。可传输表空间 功能可以轻松地将表空间从正在运行的 MySQL 服务器实例复制到另一个正在运行的实例,或者在同一实例上执行恢复。这两个选项都接受一个或多个分区名称的逗号分隔列表。例如:ALTER TABLE t1 DISCARD PARTITION p2, p3 TABLESPACE;ALTER TABLE t1 IMPORT PARTITION p2, p3 TABLESPACE;在子分区表上运行
DISCARD PARTITION ... TABLESPACE和IMPORT PARTITION ... TABLESPACE时,允许使用分区名称和子分区名称。当指定分区名称时,将包括该分区的子分区。可传输表空间功能也支持复制或恢复分区后的
InnoDB表。更多信息,请参见章节 17.6.1.3,“导入InnoDB表”。支持重命名分区表。您可以间接地使用
ALTER TABLE ... REORGANIZE PARTITION重命名单个分区;但是,此操作会复制分区的数据。要从选定的分区中删除行,请使用
TRUNCATE PARTITION选项。此选项接受一个或多个逗号分隔的分区名称列表。考虑由以下语句创建的表t1:CREATE TABLE t1 ( id INT, year_col INT ) PARTITION BY RANGE (year_col) ( PARTITION p0 VALUES LESS THAN (1991), PARTITION p1 VALUES LESS THAN (1995), PARTITION p2 VALUES LESS THAN (1999), PARTITION p3 VALUES LESS THAN (2003), PARTITION p4 VALUES LESS THAN (2007) );要删除分区
p0中的所有行,请使用以下语句:ALTER TABLE t1 TRUNCATE PARTITION p0;刚刚显示的语句与以下
DELETE语句具有相同的效果:DELETE FROM t1 WHERE year_col < 1991;截断多个分区时,分区不必是连续的:这可以极大地简化分区表的删除操作,否则,如果使用
DELETE语句完成,则需要非常复杂的WHERE条件。例如,以下语句删除分区p1和p3中的所有行:ALTER TABLE t1 TRUNCATE PARTITION p1, p3;等效的
DELETE语句如下所示:DELETE FROM t1 WHERE (year_col >= 1991 AND year_col < 1995) OR (year_col >= 2003 AND year_col < 2007);如果您使用
ALL关键字代替分区名称列表,则该语句将对所有表分区执行操作。TRUNCATE PARTITION仅删除行;它不会更改表本身或其任何分区的定义。要验证行是否已删除,请使用如下查询检查
INFORMATION_SCHEMA.PARTITIONS表:SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't1';COALESCE PARTITION可以与按HASH或KEY分区表一起使用,以将分区数量减少number个。假设您创建了表t2,如下所示:CREATE TABLE t2 ( name VARCHAR (30), started DATE ) PARTITION BY HASH( YEAR(started) ) PARTITIONS 6;要将
t2使用的分区数量从6个减少到4个,请使用以下语句:ALTER TABLE t2 COALESCE PARTITION 2;最后
number个分区中包含的数据将合并到剩余分区中。在这种情况下,分区4和5将合并到前4个分区(编号为0、1、2和3的分区)中。要更改分区表使用的部分而非所有分区,可以使用
REORGANIZE PARTITION。该语句可以多种方式使用:-
将一组分区合并到单个分区中。这是通过在
partition_names列表中命名多个分区并为partition_definition提供单个定义来完成的。 -
将现有分区拆分为多个分区。通过为
partition_names命名单个分区并提供多个partition_definitions来完成此操作。 -
要更改使用
VALUES LESS THAN定义的子集分区的范围,或使用VALUES IN定义的子集分区的列表值。
Note对于尚未明确命名的分区,MySQL 自动提供默认名称
p0、p1、p2等。子分区也是如此。有关
ALTER TABLE ... REORGANIZE PARTITION语句的更多详细信息和示例,请参阅第 26.3.1 节“管理范围和列表分区”。 -
-
要将表分区或子分区与表交换,请使用
ALTER TABLE ... EXCHANGE PARTITION语句——也就是说,将分区或子分区中任何现有行移动到非分区表,并将非分区表中任何现有行移动到表分区或子分区。一旦使用
ALGORITHM=INSTANT向分区表添加了一个或多个列,就不再可能与该表交换分区。有关使用信息和示例,请参阅 第 26.3.3 节“与表交换分区和子分区”。
-
几个选项提供了类似于
CHECK TABLE和REPAIR TABLE等语句为非分区表实现的分区维护和修复功能(也支持分区表;更多信息,请参见 第 15.7.3 节“表维护语句”)。这些包括ANALYZE PARTITION、CHECK PARTITION、OPTIMIZE PARTITION、REBUILD PARTITION和REPAIR PARTITION。这些选项中的每一个都采用partition_names子句,该子句由一个或多个分区名称组成,并用逗号分隔。分区必须已存在于目标表中。您也可以使用ALL关键字代替partition_names,在这种情况下,该语句将作用于所有表分区。有关更多信息和示例,请参阅 第 26.3.4 节“分区的维护”。InnoDB目前不支持每个分区的优化;ALTER TABLE ... OPTIMIZE PARTITION会导致整个表被重建和分析,并发出相应的警告。(错误 #11751825,错误 #42822)要解决此问题,请改用ALTER TABLE ... REBUILD PARTITION和ALTER TABLE ... ANALYZE PARTITION。ANALYZE PARTITION、CHECK PARTITION、OPTIMIZE PARTITION和REPAIR PARTITION选项不支持未分区的表。 -
REMOVE PARTITIONING允许您删除表的分区,而不会影响表或其数据。此选项可以与其他ALTER TABLE选项(例如用于添加、删除或重命名列或索引的选项)结合使用。 -
在
ALTER TABLE中使用ENGINE选项可以更改表使用的存储引擎,而不会影响分区。目标存储引擎必须提供自己的分区处理程序。只有InnoDB和NDB存储引擎具有原生分区处理程序;MySQL 8.3 中当前不支持NDB。
ALTER TABLE 语句可以在其他更改规范之外包含 PARTITION BY 或 REMOVE PARTITIONING 子句,但 PARTITION BY 或 REMOVE PARTITIONING 子句必须在任何其他规范之后最后指定。
ADD PARTITION、DROP PARTITION、COALESCE PARTITION、REORGANIZE PARTITION、ANALYZE PARTITION、CHECK PARTITION 和 REPAIR PARTITION 选项不能与单个 ALTER TABLE 中的其他更改规范组合使用,因为刚刚列出的选项作用于单个分区。有关更多信息,请参阅 第 15.1.9.1 节“ALTER TABLE 分区操作”。
在给定的 ALTER TABLE 语句中,以下选项中的每一个都只能使用一次:PARTITION BY、ADD PARTITION、DROP PARTITION、TRUNCATE PARTITION、EXCHANGE PARTITION、REORGANIZE PARTITION 或 COALESCE PARTITION、ANALYZE PARTITION、CHECK PARTITION、OPTIMIZE PARTITION、REBUILD PARTITION、REMOVE PARTITIONING。
例如,以下两个语句无效:
ALTER TABLE t1 ANALYZE PARTITION p1, ANALYZE PARTITION p2;
ALTER TABLE t1 ANALYZE PARTITION p1, CHECK PARTITION p2;
在第一种情况下,您可以使用单个 ANALYZE PARTITION 选项列出要分析的两个分区,从而同时分析表 t1 的分区 p1 和 p2,如下所示:
ALTER TABLE t1 ANALYZE PARTITION p1, p2;
在第二种情况下,无法同时对同一表的不同分区执行 ANALYZE 和 CHECK 操作。相反,您必须发出两个单独的语句,如下所示:
ALTER TABLE t1 ANALYZE PARTITION p1;
ALTER TABLE t1 CHECK PARTITION p2;
REBUILD 操作目前不支持子分区。明确禁止对子分区使用 REBUILD 关键字,如果使用,会导致 ALTER TABLE 失败并出现错误。
CHECK PARTITION 和 REPAIR PARTITION 操作在要检查或修复的分区包含任何重复键错误时失败。
有关这些语句的更多信息,请参见 第 26.3.4 节“分区维护”。