200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > mysql 分区个数限制_mysql8 参考手册-分区的限制

mysql 分区个数限制_mysql8 参考手册-分区的限制

时间:2022-09-07 19:48:13

相关推荐

mysql 分区个数限制_mysql8 参考手册-分区的限制

本节讨论了对MySQL分区支持的当前限制。

禁止使用的构造。 分区表达式中不允许以下构造:

存储过程,存储函数,UDF或插件。

声明的变量或用户变量。

有关分区表达式中允许的SQL函数的列表,请参见 第23.6.3节“与函数相关的分区限制”。

算术和逻辑运算符。 分区表达式中允许 使用算术运算符 +, -和 *。但是,结果必须是一个整数值或NULL(关于[LINEAR] KEY分区的情况除外 ,如本章其他地方所述;有关更多信息,请参见 第23.2节“分区类型”)。

该DIV运营商还支持; 该/操作是不允许的。

该位运营商 |, &, ^, <>,并 ~没有在分区表达式允许的。

服务器SQL模式。 使用用户定义的分区的表在创建时不会保留有效的SQL模式。如本手册其他部分所述(请参见 第5.1.11节“服务器SQL模式”),许多MySQL函数和运算符的结果可能会根据服务器SQL模式而变化。因此,在创建分区表之后随时更改SQL模式可能会导致此类表的行为发生重大变化,并且很容易导致数据损坏或丢失。由于这些原因,强烈建议您不要在创建分区表之后更改服务器SQL模式。

对于服务器SQL模式中的这种更改(使分区表不可用),请考虑以下 CREATE TABLE语句,只有在该NO_UNSIGNED_SUBTRACTION模式有效时,该语句才能成功执行 :

mysql> SELECT @@sql_mode;

+------------+

| @@sql_mode |

+------------+

| |

+------------+

1 row in set (0.00 sec)

mysql> CREATE TABLE tu (c1 BIGINT UNSIGNED)

-> PARTITION BY RANGE(c1 - 10) (

-> PARTITION p0 VALUES LESS THAN (-5),

-> PARTITION p1 VALUES LESS THAN (0),

-> PARTITION p2 VALUES LESS THAN (5),

-> PARTITION p3 VALUES LESS THAN (10),

-> PARTITION p4 VALUES LESS THAN (MAXVALUE)

-> );

ERROR 1563 (HY000): Partition constant is out of partition function domain

mysql> SET sql_mode='NO_UNSIGNED_SUBTRACTION';

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@sql_mode;

+-------------------------+

| @@sql_mode |

+-------------------------+

| NO_UNSIGNED_SUBTRACTION |

+-------------------------+

1 row in set (0.00 sec)

mysql> CREATE TABLE tu (c1 BIGINT UNSIGNED)

-> PARTITION BY RANGE(c1 - 10) (

-> PARTITION p0 VALUES LESS THAN (-5),

-> PARTITION p1 VALUES LESS THAN (0),

-> PARTITION p2 VALUES LESS THAN (5),

-> PARTITION p3 VALUES LESS THAN (10),

-> PARTITION p4 VALUES LESS THAN (MAXVALUE)

-> );

Query OK, 0 rows affected (0.05 sec)

如果NO_UNSIGNED_SUBTRACTION在创建后删除 服务器SQL模式tu,则可能不再能够访问此表:

mysql> SET sql_mode='';

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM tu;

ERROR 1563 (HY000): Partition constant is out of partition function domain

mysql> INSERT INTO tu VALUES (20);

ERROR 1563 (HY000): Partition constant is out of partition function domain

服务器SQL模式还会影响分区表的复制。主服务器和从服务器上不同的SQL模式可能导致对分区表达式的求值方式有所不同。这可能导致分区之间的数据分配在给定表的主副本和从属副本中有所不同,甚至可能导致在成功在主副本上的分区表中插入而在从属副本上失败。为了获得最佳结果,您应该始终在主服务器和从服务器上使用相同的服务器SQL模式。

性能注意事项。 下表列出了分区操作对性能的一些影响:

文件系统操作。 分区和重新分区操作(例如 ALTER TABLE使用PARTITION BY ...,, REORGANIZE PARTITION或REMOVE PARTITIONING)取决于文件系统操作的实现。这意味着这些操作的速度受以下因素影响,例如文件系统类型和特征,磁盘速度,交换空间,操作系统的文件处理效率以及与文件处理有关的MySQL服务器选项和变量。特别是,您应确保 large_files_support已启用它并且 open_files_limit已正确设置。涉及的分区和重新分区操作InnoDB通过启用可以使表更有效 innodb_file_per_table。

另请参阅 最大分区数。

表锁。 通常,对表执行分区操作的进程对表进行写锁定。从此类表中读取的数据相对不受影响;挂起, INSERT并且 UPDATE在分区操作完成后立即执行操作。有关InnoDB此限制的特定例外,请参阅“ 分区操作”。

索引;分区修剪。 与非分区表一样,正确使用索引可以显着加快对分区表的查询。此外,设计分区表和对这些表的查询以利用 分区修剪可以极大地提高性能。有关更多信息,请参见 第23.4节“分区修剪”。

分区表支持索引条件下推。请参见第8.2.1.6节“索引条件下推优化”。

LOAD DATA的性能。 在MySQL 8.0中,LOAD DATA使用缓冲来提高性能。您应该意识到,缓冲区为每个分区使用130 KB内存来实现此目的。

最大分区数。 对于不使用NDB存储引擎的给定表,最大分区数为8192。此数目包括子分区。

使用NDB存储引擎的表的用户定义分区的最大可能数目取决于所使用的NDB Cluster软件的版本,数据节点的数目以及其他因素。有关更多信息,请参见 NDB和用户定义的分区。

如果在创建具有大量分区(但小于最大分区)的表时,遇到错误消息,例如来自存储引擎的错误消息 :打开文件时资源不足,则可能可以解决该问题通过增加open_files_limit系统变量的值 。但是,这取决于操作系统,可能并非在所有平台上都是可行或不可取的。有关更多信息,请参见 第B.4.2.17节“找不到文件和类似错误”。在某些情况下,由于其他原因,也不建议使用大量(数百个)分区,因此使用更多分区不会自动导致更好的结果。

另请参阅 文件系统操作。

分区的InnoDB表不支持外键。 使用InnoDB 存储引擎的分区表不支持外键。更具体地说,这意味着以下两个陈述是正确的:

InnoDB使用用户定义的分区 的表的定义都不能包含外键引用。没有InnoDB表,其定义中包含外键引用可以被划分。

没有InnoDB表定义可能包含一个外键引用到用户分区表; InnoDB具有用户定义分区的表不能 包含外键引用的列。

刚刚列出的限制范围包括所有使用InnoDB存储引擎的表。 CREATE TABLE而ALTER TABLE 这将导致表违反这些限制的语句是不允许的。

ALTER TABLE ... ORDER BY。 针对分区表运行 的语句仅导致每个分区内的行排序。 ALTER TABLE ... ORDER BY column

修改主键对REPLACE语句的影响。 在某些情况下(请参见 第23.6.1节“分区键,主键和唯一键”),可能需要修改表的主键。请注意,如果您的应用程序使用了REPLACE 语句并执行了此操作,则这些语句的结果可能会发生巨大变化。有关更多信息和示例,请参见第13.2.9节“ REPLACE语句”。

FULLTEXT索引。 分区表不支持FULLTEXT 索引或搜索。

空间列。 具有空间数据类型(例如POINT 或GEOMETRY不能在分区表中使用)的列。

临时表。 临时表无法分区。

日志表。 无法对日志表进行分区;ALTER TABLE ... PARTITION BY ...这样的表上的 语句失败,并显示错误。

分区键的数据类型。 分区键必须是整数列或解析为整数的表达式。ENUM不能使用采用列的表达式 。列或表达式值也可以是NULL;请参见第23.2.7节“ MySQL分区如何处理NULL”。

此限制有两个例外:

当通过[ LINEAR]进行 分区时KEY,可以使用除以外的任何有效MySQL数据类型的列 TEXT或将其 BLOB用作分区键,因为内部键哈希函数会从这些类型中生成正确的数据类型。例如,以下两个 CREATE TABLE语句有效:

CREATE TABLE tkc (c1 CHAR)

PARTITION BY KEY(c1)

PARTITIONS 4;

CREATE TABLE tke

( c1 ENUM('red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet') )

PARTITION BY LINEAR KEY(c1)

PARTITIONS 6;

通过RANGE COLUMNS或进行 分区时LIST COLUMNS,可以使用字符串 DATE,和 DATETIME列。例如,以下每个CREATE TABLE语句均有效:

CREATE TABLE rc (c1 INT, c2 DATE)

PARTITION BY RANGE COLUMNS(c2) (

PARTITION p0 VALUES LESS THAN('1990-01-01'),

PARTITION p1 VALUES LESS THAN('1995-01-01'),

PARTITION p2 VALUES LESS THAN('2000-01-01'),

PARTITION p3 VALUES LESS THAN('-01-01'),

PARTITION p4 VALUES LESS THAN(MAXVALUE)

);

CREATE TABLE lc (c1 INT, c2 CHAR(1))

PARTITION BY LIST COLUMNS(c2) (

PARTITION p0 VALUES IN('a', 'd', 'g', 'j', 'm', 'p', 's', 'v', 'y'),

PARTITION p1 VALUES IN('b', 'e', 'h', 'k', 'n', 'q', 't', 'w', 'z'),

PARTITION p2 VALUES IN('c', 'f', 'i', 'l', 'o', 'r', 'u', 'x', NULL)

);

前述任何例外均不适用于 BLOB或 TEXT列类型。

子查询。 分区键可能不是子查询,即使该子查询解析为整数值或NULL。

键分区不支持列索引前缀。 创建按键进行分区的表时,该分区的分区功能中不会使用分区键中使用列前缀的任何列。考虑以下 CREATE TABLE语句,该语句具有三VARCHAR列,其主键使用所有三列并为其中两列指定前缀:

CREATE TABLE t1 (

a VARCHAR(10000),

b VARCHAR(25),

c VARCHAR(10),

PRIMARY KEY (a(10), b, c(2))

) PARTITION BY KEY() PARTITIONS 2;

该语句被接受,但实际上创建的结果表就像您已发出以下语句一样,仅使用不包含b分区键前缀(主列)的主键列 :

CREATE TABLE t1 (

a VARCHAR(10000),

b VARCHAR(25),

c VARCHAR(10),

PRIMARY KEY (a(10), b, c(2))

) PARTITION BY KEY(b) PARTITIONS 2;

在MySQL 8.0.21之前,没有发出警告或提供任何其他指示,除非为分区键指定的所有列都使用前缀(在这种情况下,该语句失败,但带有误导性的错误消息),除非如图所示:

mysql> CREATE TABLE t2 (

-> a VARCHAR(10000),

-> b VARCHAR(25),

-> c VARCHAR(10),

-> PRIMARY KEY (a(10), b(5) c(2))

-> ) PARTITION BY KEY() PARTITIONS 2;

ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the

table's partitioning function

执行ALTER TABLE或升级此类表时也会发生这种情况。

从MySQL 8.0.21开始,不再允许这种行为(并且在将来的MySQL版本中可能会删除)。从MySQL 8.0.21开始,使用一个或多个在分区键中带有前缀的列会为每个此类列产生警告,如下所示:

mysql> CREATE TABLE t1 (

-> a VARCHAR(10000),

-> b VARCHAR(25),

-> c VARCHAR(10),

-> PRIMARY KEY (a(10), b, c(2))

-> ) PARTITION BY KEY() PARTITIONS 2;

Query OK, 0 rows affected, 2 warnings (1.25 sec)

mysql> SHOW WARNINGS\G

*************************** 1. row ***************************

Level: Warning

Code: 1681

Message: Column 'test.t1.a' having prefix key part 'a(10)' is ignored by the

partitioning function. Use of prefixed columns in the PARTITION BY KEY() clause

is deprecated and will be removed in a future release.

*************************** 2. row ***************************

Level: Warning

Code: 1681

Message: Column 'test.t1.c' having prefix key part 'c(2)' is ignored by the

partitioning function. Use of prefixed columns in the PARTITION BY KEY() clause

is deprecated and will be removed in a future release.

2 rows in set (0.00 sec)

这包括通过使用空PARTITION BY KEY()子句将分区函数中使用的列隐式定义为表的主键中的列的情况。

在MySQL 8.0.21和更高版本中,如果为分区键指定的所有列均使用前缀,则CREATE TABLE所使用的语句将失败,并显示一条错误消息,以正确识别问题:

mysql> CREATE TABLE t1 (

-> a VARCHAR(10000),

-> b VARCHAR(25),

-> c VARCHAR(10),

-> PRIMARY KEY (a(10), b(5), c(2))

-> ) PARTITION BY KEY() PARTITIONS 2;

ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's

partitioning function (prefixed columns are not considered).

子分区问题。 子分区必须使用HASH或 KEY分区。只有 RANGE和LIST分区可以再分区;HASH并且 KEY分区不能再分区。

SUBPARTITION BY KEY要求显式指定一个或多个子分区列,与的情况不同PARTITION BY KEY,可以将其省略(在这种情况下,默认情况下使用表的主键列)。考虑以下语句创建的表:

CREATE TABLE ts (

id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,

name VARCHAR(30)

);

您可以KEY使用如下语句创建具有相同列的表,并按进行分区 :

CREATE TABLE ts (

id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,

name VARCHAR(30)

)

PARTITION BY KEY()

PARTITIONS 4;

前面的语句就好像是这样写的,表的主键列用作分区列:

CREATE TABLE ts (

id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,

name VARCHAR(30)

)

PARTITION BY KEY(id)

PARTITIONS 4;

但是,以下尝试使用默认列作为子分区列创建子分区表的语句失败,并且必须指定该列才能使语句成功,如下所示:

mysql> CREATE TABLE ts (

-> id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,

-> name VARCHAR(30)

-> )

-> PARTITION BY RANGE(id)

-> SUBPARTITION BY KEY()

-> SUBPARTITIONS 4

-> (

-> PARTITION p0 VALUES LESS THAN (100),

-> PARTITION p1 VALUES LESS THAN (MAXVALUE)

-> );

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that

corresponds to your MySQL server version for the right syntax to use near ')

mysql> CREATE TABLE ts (

-> id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,

-> name VARCHAR(30)

-> )

-> PARTITION BY RANGE(id)

-> SUBPARTITION BY KEY(id)

-> SUBPARTITIONS 4

-> (

-> PARTITION p0 VALUES LESS THAN (100),

-> PARTITION p1 VALUES LESS THAN (MAXVALUE)

-> );

Query OK, 0 rows affected (0.07 sec)

这是一个已知问题(请参见Bug#51470)。

DATA DIRECTORY和INDEX DIRECTORY选项。 表级DATA DIRECTORY和INDEX DIRECTORY选项将被忽略(请参见Bug#32091)。您可以将这些选项用于InnoDB表的单个分区或子分区。

修复和重建分区表。 该声明CHECK TABLE, OPTIMIZE TABLE, ANALYZE TABLE,并且 REPAIR TABLE都支持分区表。

此外,您可以ALTER TABLE ... REBUILD PARTITION用来重建分区表的一个或多个分区。ALTER TABLE ... REORGANIZE PARTITION也导致分区被重建。有关这两个语句的更多信息,请参见 第13.1.9节“ ALTER TABLE语句”。

ANALYZE,CHECK, OPTIMIZE,REPAIR,和 TRUNCATE操作与子分区支持。请参见 第13.1.9.1节“ ALTER TABLE分区操作”。

分区和子分区的文件名定界符。 表分区和子分区文件名包含生成的定界符,例如#P#和 #SP#。此类分隔符的字母大小写可以变化,因此不应依赖。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。