Table of Contents
This section discusses current restrictions and limitations on MySQL partitioning support.
Prohibited constructs. The following constructs are not permitted in partitioning expressions:
Stored procedures, stored functions, UDFs, or plugins.
Declared variables or user variables.
For a list of SQL functions which are permitted in partitioning expressions, see Section 6.3, “Partitioning Limitations Relating to Functions”.
Arithmetic and logical operators.
Use of the arithmetic operators
+,
-, and
* is permitted in
partitioning expressions. However, the result must be an integer
value or NULL (except in the case of
[LINEAR] KEY partitioning, as discussed
elsewhere in this chapter; see
Chapter 3, Partitioning Types, for more information).
The DIV operator is also supported,
and the / operator
is not permitted. (Bug #30188, Bug #33182)
The bit operators
|,
&,
^,
<<,
>>, and
~ are not
permitted in partitioning expressions.
HANDLER statements.
In MySQL 5.6, the
HANDLER statement is not
supported with partitioned tables.
Server SQL mode. Tables employing user-defined partitioning do not preserve the SQL mode in effect at the time that they were created. As discussed in Server SQL Modes, the results of many MySQL functions and operators may change according to the server SQL mode. Therefore, a change in the SQL mode at any time after the creation of partitioned tables may lead to major changes in the behavior of such tables, and could easily lead to corruption or loss of data. For these reasons, it is strongly recommended that you never change the server SQL mode after creating partitioned tables.
Examples. The following examples illustrate some changes in behavior of partitioned tables due to a change in the server SQL mode:
Error handling.
Suppose that you create a partitioned table whose
partitioning expression is one such as
or column DIV 0, as shown here:
column MOD
0
mysql>CREATE TABLE tn (c1 INT)->PARTITION BY LIST(1 DIV c1) (->PARTITION p0 VALUES IN (NULL),->PARTITION p1 VALUES IN (1)->);Query OK, 0 rows affected (0.05 sec)
The default behavior for MySQL is to return
NULL for the result of a division by zero,
without producing any errors:
mysql>SELECT @@sql_mode;+------------+ | @@sql_mode | +------------+ | | +------------+ 1 row in set (0.00 sec) mysql>INSERT INTO tn VALUES (NULL), (0), (1);Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0
However, changing the server SQL mode to treat division by
zero as an error and to enforce strict error handling causes
the same INSERT statement to
fail, as shown here:
mysql>SET sql_mode='STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO';Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO tn VALUES (NULL), (0), (1);ERROR 1365 (22012): Division by 0
Table accessibility.
Sometimes a change in the server SQL mode can make
partitioned tables unusable. The following
CREATE TABLE statement can be
executed successfully only if the
NO_UNSIGNED_SUBTRACTION
mode is in effect:
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)
If you remove the
NO_UNSIGNED_SUBTRACTION
server SQL mode after creating tu, you may
no longer be able to access this table:
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
Server SQL modes also impact replication of partitioned tables. Differing SQL modes on master and slave can lead to partitioning expressions being evaluated differently; this can cause the distribution of data among partitions to be different in the master's and slave's copies of a given table, and may even cause inserts into partitioned tables that succeed on the master to fail on the slave. For best results, you should always use the same server SQL mode on the master and on the slave.
Performance considerations. Some affects of partitioning operations on performance are given in the following list:
File system operations.
Partitioning and repartitioning operations (such as
ALTER
TABLE with PARTITION BY ...,
REORGANIZE PARTITIONS, or REMOVE
PARTITIONING) depend on file system operations for
their implementation. This means that the speed of these
operations is affected by such factors as file system type
and characteristics, disk speed, swap space, file handling
efficiency of the operating system, and MySQL server options
and variables that relate to file handling. In particular,
you should make sure that
large_files_support is
enabled and that
open_files_limit is set
properly. For partitioned tables using the
MyISAM storage engine, increasing
myisam_max_sort_file_size
may improve performance; partitioning and repartitioning
operations involving InnoDB tables may be
made more efficient by enabling
innodb_file_per_table.
See also Maximum number of partitions.
MyISAM and partition file descriptor usage.
For a partitioned MyISAM table,
MySQL uses 2 file descriptors for each partition, for each
such table that is open. This means that you need many more
file descriptors to perform operations on a partitioned
MyISAM table than on a table which is
identical to it except that the latter table is not
partitioned, particularly when performing
ALTER
TABLE operations.
Assume a MyISAM table t
with 100 partitions, such as the table created by this SQL
statement:
CREATE TABLE t (c1 VARCHAR(50)) PARTITION BY KEY (c1) PARTITIONS 100 ENGINE=MYISAM;
For brevity, we use KEY partitioning for
the table shown in this example, but file descriptor usage
as described here applies to all partitioned
MyISAM tables, regardless of the type of
partitioning that is employed. Partitioned tables using
other storage engines such as
InnoDB are not affected by this
issue.
Now assume that you wish to repartition t
so that it has 101 partitions, using the statement shown here:
ALTER TABLE t PARTITION BY KEY (c1) PARTITIONS 101;
To process this ALTER TABLE statement,
MySQL uses 402 file descriptors—that is, two for each of
the 100 original partitions, plus two for each of the 101 new
partitions. This is because all partitions (old and new) must
be opened concurrently during the reorganization of the table
data. It is recommended that, if you expect to perform such
operations, you should make sure that
--open-files-limit is not set
too low to accommodate them.
Table locks.
The process executing a partitioning operation on a table
takes a write lock on the table. Reads from such tables are
relatively unaffected; pending
INSERT and
UPDATE operations are
performed as soon as the partitioning operation has
completed.
Storage engine.
Partitioning operations, queries, and update operations
generally tend to be faster with MyISAM
tables than with InnoDB or
NDB tables.
Indexes; partition pruning. As with nonpartitioned tables, proper use of indexes can speed up queries on partitioned tables significantly. In addition, designing partitioned tables and queries on these tables to take advantage of partition pruning can improve performance dramatically. See Chapter 5, Partition Pruning, for more information.
Index condition pushdown is not supported for partitioned tables. See Index Condition Pushdown Optimization.
Performance with LOAD DATA.
In MySQL 5.6, LOAD
DATA uses buffering to improve performance. You
should be aware that the buffer uses 130 KB memory per
partition to achieve this.
Maximum number of partitions.
Prior to MySQL 5.6.7, the maximum possible number of partitions
for a given table not using the NDB
storage engine was 1024. Beginning with MySQL 5.6.7, this limit
is increased to 8192 partitions. Regardless of the MySQL Server
version, this maximum includes subpartitions.
The maximum possible number of user-defined partitions for a table
using the NDB storage engine is
determined according to the version of the MySQL Cluster software
being used, the number of data nodes, and other factors. See
NDB and user-defined partitioning,
for more information.
If, when creating tables with a large number of partitions (but
less than the maximum), you encounter an error message such as
Got error ... from storage engine: Out of resources
when opening file, you may be able to address the
issue by increasing the value of the
open_files_limit system variable.
However, this is dependent on the operating system, and may not be
possible or advisable on all platforms; see
File Not Found and Similar Errors, for more information.
In some cases, using large numbers (hundreds) of partitions may
also not be advisable due to other concerns, so using more
partitions does not automatically lead to better results.
See also File system operations.
Query cache not supported. The query cache is not supported for partitioned tables. Beginning with MySQL 5.6.5, the query cache is automatically disabled for queries involving partitioned tables, and cannot be enabled for such queries. (Bug #53775)
Per-partition key caches.
In MySQL 5.6, key caches are supported for
partitioned MyISAM tables, using
the CACHE INDEX and
LOAD INDEX INTO
CACHE statements. Key caches may be defined for one,
several, or all partitions, and indexes for one, several, or all
partitions may be preloaded into key caches.
Foreign keys not supported for partitioned InnoDB tables.
Partitioned tables using the InnoDB
storage engine do not support foreign keys. More specifically,
this means that the following two statements are true:
No definition of an InnoDB table employing
user-defined partitioning may contain foreign key references;
no InnoDB table whose definition contains
foreign key references may be partitioned.
No InnoDB table definition may contain a
foreign key reference to a user-partitioned table; no
InnoDB table with user-defined partitioning
may contain columns referenced by foreign keys.
The scope of the restrictions just listed includes all tables that
use the InnoDB storage engine.
CREATE
TABLE and ALTER TABLE
statements that would result in tables violating these
restrictions are not allowed.
ALTER TABLE ... ORDER BY.
An ALTER TABLE ... ORDER BY
statement run
against a partitioned table causes ordering of rows only within
each partition.
column
Effects on REPLACE statements by modification of primary keys.
It can be desirable in some cases (see
Section 6.1, “Partitioning Keys, Primary Keys, and Unique Keys”)
to modify a table's primary key. Be aware that, if your
application uses REPLACE
statements and you do this, the results of these statements can
be drastically altered. See REPLACE Syntax, for more
information and an example.
FULLTEXT indexes.
Partitioned tables do not support FULLTEXT
indexes or searches, even for partitioned tables employing the
InnoDB or
MyISAM storage engine.
Spatial columns.
Columns with spatial data types such as POINT
or GEOMETRY cannot be used in partitioned
tables.
Temporary tables. Temporary tables cannot be partitioned. (Bug #17497)
Log tables.
It is not possible to partition the log tables; an
ALTER
TABLE ... PARTITION BY ... statement on such a table
fails with an error.
Data type of partitioning key.
A partitioning key must be either an integer column or an
expression that resolves to an integer. Expressions employing
ENUM columns cannot be used. The
column or expression value may also be NULL.
(See Section 3.7, “How MySQL Partitioning Handles NULL”.)
There are two exceptions to this restriction:
When partitioning by [LINEAR] KEY, it is
possible to use columns of any valid MySQL data type other
than TEXT or
BLOB as partitioning keys,
because MySQL's internal key-hashing functions produce
the correct data type from these types. For example, the
following two CREATE TABLE
statements are valid:
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;
When partitioning by RANGE COLUMNS or
LIST COLUMNS, it is possible to use string,
DATE, and
DATETIME columns. For example,
each of the following CREATE
TABLE statements is valid:
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('2005-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)
);
Neither of the preceding exceptions applies to
BLOB or
TEXT column types.
Subqueries.
A partitioning key may not be a subquery, even if that subquery
resolves to an integer value or NULL.
Issues with subpartitions.
Subpartitions must use HASH or
KEY partitioning. Only
RANGE and LIST partitions
may be subpartitioned; HASH and
KEY partitions cannot be subpartitioned.
SUBPARTITION BY KEY requires that the
subpartitioning column or columns be specified explicitly, unlike
the case with PARTITION BY KEY, where it can be
omitted (in which case the table's primary key column is used
by default). Consider the table created by this statement:
CREATE TABLE ts (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30)
);
You can create a table having the same columns, partitioned by
KEY, using a statement such as this one:
CREATE TABLE ts (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30)
)
PARTITION BY KEY()
PARTITIONS 4;
The previous statement is treated as though it had been written like this, with the table's primary key column used as the partitioning column:
CREATE TABLE ts (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30)
)
PARTITION BY KEY(id)
PARTITIONS 4;
However, the following statement that attempts to create a subpartitioned table using the default column as the subpartitioning column fails, and the column must be specified for the statement to succeed, as shown here:
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)
This is a known issue (see Bug #51470).
DELAYED option not supported.
Use of INSERT DELAYED to insert
rows into a partitioned table is not supported. Attempting to do
so fails with an error.
DATA DIRECTORY and INDEX DIRECTORY options.
DATA DIRECTORY and INDEX
DIRECTORY are subject to the following restrictions
when used with partitioned tables:
Table-level DATA DIRECTORY and
INDEX DIRECTORY options are ignored (see
Bug #32091).
On Windows, the DATA DIRECTORY and
INDEX DIRECTORY options are not supported
for individual partitions or subpartitions of
MyISAM tables (Bug #30459).
However, you can use DATA DIRECTORY for
individual partitions or subpartitions of
InnoDB tables.
Repairing and rebuilding partitioned tables.
The statements CHECK TABLE,
OPTIMIZE TABLE,
ANALYZE TABLE, and
REPAIR TABLE are supported for
partitioned tables.
In addition, you can use ALTER TABLE ... REBUILD
PARTITION to rebuild one or more partitions of a
partitioned table; ALTER TABLE ... REORGANIZE
PARTITION also causes partitions to be rebuilt. See
ALTER TABLE Syntax, for more information about these
two statements.
mysqlcheck, myisamchk, and myisampack are not supported with partitioned tables.
FOR EXPORT option (FLUSH TABLES).
The FLUSH
TABLES statement's FOR EXPORT
option is not supported for partitioned
InnoDB tables in MySQL 5.6.16 and earlier.
(Bug #16943907)
This section discusses the relationship of partitioning keys with primary keys and unique keys. The rule governing this relationship can be expressed as follows: All columns used in the partitioning expression for a partitioned table must be part of every unique key that the table may have.
In other words, every unique key on the table must use every column in the table's partitioning expression. (This also includes the table's primary key, since it is by definition a unique key. This particular case is discussed later in this section.) For example, each of the following table creation statements is invalid:
CREATE TABLE t1 (
col1 INT NOT NULL,
col2 DATE NOT NULL,
col3 INT NOT NULL,
col4 INT NOT NULL,
UNIQUE KEY (col1, col2)
)
PARTITION BY HASH(col3)
PARTITIONS 4;
CREATE TABLE t2 (
col1 INT NOT NULL,
col2 DATE NOT NULL,
col3 INT NOT NULL,
col4 INT NOT NULL,
UNIQUE KEY (col1),
UNIQUE KEY (col3)
)
PARTITION BY HASH(col1 + col3)
PARTITIONS 4;
In each case, the proposed table would have at least one unique key that does not include all columns used in the partitioning expression.
Each of the following statements is valid, and represents one way in which the corresponding invalid table creation statement could be made to work:
CREATE TABLE t1 (
col1 INT NOT NULL,
col2 DATE NOT NULL,
col3 INT NOT NULL,
col4 INT NOT NULL,
UNIQUE KEY (col1, col2, col3)
)
PARTITION BY HASH(col3)
PARTITIONS 4;
CREATE TABLE t2 (
col1 INT NOT NULL,
col2 DATE NOT NULL,
col3 INT NOT NULL,
col4 INT NOT NULL,
UNIQUE KEY (col1, col3)
)
PARTITION BY HASH(col1 + col3)
PARTITIONS 4;
This example shows the error produced in such cases:
mysql>CREATE TABLE t3 (->col1 INT NOT NULL,->col2 DATE NOT NULL,->col3 INT NOT NULL,->col4 INT NOT NULL,->UNIQUE KEY (col1, col2),->UNIQUE KEY (col3)->)->PARTITION BY HASH(col1 + col3)->PARTITIONS 4;ERROR 1491 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function
The CREATE TABLE statement fails
because both col1 and col3
are included in the proposed partitioning key, but neither of
these columns is part of both of unique keys on the table. This
shows one possible fix for the invalid table definition:
mysql>CREATE TABLE t3 (->col1 INT NOT NULL,->col2 DATE NOT NULL,->col3 INT NOT NULL,->col4 INT NOT NULL,->UNIQUE KEY (col1, col2, col3),->UNIQUE KEY (col3)->)->PARTITION BY HASH(col3)->PARTITIONS 4;Query OK, 0 rows affected (0.05 sec)
In this case, the proposed partitioning key
col3 is part of both unique keys, and the
table creation statement succeeds.
The following table cannot be partitioned at all, because there is no way to include in a partitioning key any columns that belong to both unique keys:
CREATE TABLE t4 (
col1 INT NOT NULL,
col2 INT NOT NULL,
col3 INT NOT NULL,
col4 INT NOT NULL,
UNIQUE KEY (col1, col3),
UNIQUE KEY (col2, col4)
);
Since every primary key is by definition a unique key, this restriction also includes the table's primary key, if it has one. For example, the next two statements are invalid:
CREATE TABLE t5 (
col1 INT NOT NULL,
col2 DATE NOT NULL,
col3 INT NOT NULL,
col4 INT NOT NULL,
PRIMARY KEY(col1, col2)
)
PARTITION BY HASH(col3)
PARTITIONS 4;
CREATE TABLE t6 (
col1 INT NOT NULL,
col2 DATE NOT NULL,
col3 INT NOT NULL,
col4 INT NOT NULL,
PRIMARY KEY(col1, col3),
UNIQUE KEY(col2)
)
PARTITION BY HASH( YEAR(col2) )
PARTITIONS 4;
In both cases, the primary key does not include all columns referenced in the partitioning expression. However, both of the next two statements are valid:
CREATE TABLE t7 (
col1 INT NOT NULL,
col2 DATE NOT NULL,
col3 INT NOT NULL,
col4 INT NOT NULL,
PRIMARY KEY(col1, col2)
)
PARTITION BY HASH(col1 + YEAR(col2))
PARTITIONS 4;
CREATE TABLE t8 (
col1 INT NOT NULL,
col2 DATE NOT NULL,
col3 INT NOT NULL,
col4 INT NOT NULL,
PRIMARY KEY(col1, col2, col4),
UNIQUE KEY(col2, col1)
)
PARTITION BY HASH(col1 + YEAR(col2))
PARTITIONS 4;
If a table has no unique keys—this includes having no primary key—then this restriction does not apply, and you may use any column or columns in the partitioning expression as long as the column type is compatible with the partitioning type.
For the same reason, you cannot later add a unique key to a partitioned table unless the key includes all columns used by the table's partitioning expression. Consider the partitioned table created as shown here:
mysql>CREATE TABLE t_no_pk (c1 INT, c2 INT)->PARTITION BY RANGE(c1) (->PARTITION p0 VALUES LESS THAN (10),->PARTITION p1 VALUES LESS THAN (20),->PARTITION p2 VALUES LESS THAN (30),->PARTITION p3 VALUES LESS THAN (40)->);Query OK, 0 rows affected (0.12 sec)
It is possible to add a primary key to
t_no_pk using either of these
ALTER
TABLE statements:
# possible PK mysql>ALTER TABLE t_no_pk ADD PRIMARY KEY(c1);Query OK, 0 rows affected (0.13 sec) Records: 0 Duplicates: 0 Warnings: 0 # drop this PK mysql>ALTER TABLE t_no_pk DROP PRIMARY KEY;Query OK, 0 rows affected (0.10 sec) Records: 0 Duplicates: 0 Warnings: 0 # use another possible PK mysql>ALTER TABLE t_no_pk ADD PRIMARY KEY(c1, c2);Query OK, 0 rows affected (0.12 sec) Records: 0 Duplicates: 0 Warnings: 0 # drop this PK mysql>ALTER TABLE t_no_pk DROP PRIMARY KEY;Query OK, 0 rows affected (0.09 sec) Records: 0 Duplicates: 0 Warnings: 0
However, the next statement fails, because c1
is part of the partitioning key, but is not part of the proposed
primary key:
# fails with error 1503
mysql> ALTER TABLE t_no_pk ADD PRIMARY KEY(c2);
ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function
Since t_no_pk has only c1
in its partitioning expression, attempting to adding a unique
key on c2 alone fails. However, you can add a
unique key that uses both c1 and
c2.
These rules also apply to existing nonpartitioned tables that
you wish to partition using
ALTER
TABLE ... PARTITION BY. Consider a table
np_pk created as shown here:
mysql>CREATE TABLE np_pk (->id INT NOT NULL AUTO_INCREMENT,->name VARCHAR(50),->added DATE,->PRIMARY KEY (id)->);Query OK, 0 rows affected (0.08 sec)
The following
ALTER
TABLE statement fails with an error, because the
added column is not part of any unique key in
the table:
mysql>ALTER TABLE np_pk->PARTITION BY HASH( TO_DAYS(added) )->PARTITIONS 4;ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function
However, this statement using the id column
for the partitioning column is valid, as shown here:
mysql>ALTER TABLE np_pk->PARTITION BY HASH(id)->PARTITIONS 4;Query OK, 0 rows affected (0.11 sec) Records: 0 Duplicates: 0 Warnings: 0
In the case of np_pk, the only column that
may be used as part of a partitioning expression is
id; if you wish to partition this table using
any other column or columns in the partitioning expression, you
must first modify the table, either by adding the desired column
or columns to the primary key, or by dropping the primary key
altogether.
The following limitations apply to the use of storage engines with user-defined partitioning of tables.
MERGE storage engine.
User-defined partitioning and the MERGE
storage engine are not compatible. Tables using the
MERGE storage engine cannot be partitioned.
Partitioned tables cannot be merged.
FEDERATED storage engine.
Partitioning of FEDERATED tables is not
supported; it is not possible to create partitioned
FEDERATED tables.
CSV storage engine.
Partitioned tables using the CSV storage
engine are not supported; it is not possible to create
partitioned CSV tables.
InnoDB storage engine.
InnoDB foreign keys and MySQL
partitioning are not compatible. Partitioned
InnoDB tables cannot have foreign key
references, nor can they have columns referenced by foreign
keys. InnoDB tables which have or which are
referenced by foreign keys cannot be partitioned.
In addition,
ALTER
TABLE ... OPTIMIZE PARTITION does not work correctly
with partitioned tables that use the InnoDB
storage engine. Use ALTER TABLE ... REBUILD
PARTITION and ALTER TABLE ... ANALYZE
PARTITION, instead, for such tables. For more
information, see
ALTER TABLE Partition Operations.
User-defined partitioning and the NDB storage engine (MySQL Cluster).
Partitioning by KEY (including
LINEAR KEY) is the only type of
partitioning supported for the
NDB storage engine. It is not
possible under normal circumstances in MySQL Cluster NDB 7.4
to create a MySQL Cluster table using any partitioning type
other than [LINEAR] KEY,
and attempting to do so fails with an error.
Exception (not for production): It is
possible to override this restriction by setting the
new system variable on MySQL
Cluster SQL nodes to ON. If you choose to do
this, you should be aware that tables using partitioning types
other than [LINEAR] KEY are not supported in
production. In such cases, you can create and use
tables with partitioning types other than KEY
or LINEAR KEY, but you do this entirely at
your own risk.
The maximum number of partitions that can be defined for an
NDB table depends on the number of
data nodes and node groups in the cluster, the version of the
MySQL Cluster software in use, and other factors. See
NDB and user-defined partitioning,
for more information.
The maximum amount of fixed-size data that can be stored per
partition in an NDB table is 16 GB.
CREATE TABLE and
ALTER
TABLE statements that would cause a user-partitioned
NDB table not to meet either or
both of the following two requirements are not permitted, and
fail with an error:
The table must have an explicit primary key.
All columns listed in the table's partitioning expression must be part of the primary key.
Exception.
If a user-partitioned NDB table
is created using an empty column-list (that is, using
PARTITION BY KEY() or PARTITION BY
LINEAR KEY()), then no explicit primary key is
required.
Upgrading partitioned tables.
When performing an upgrade, tables which are partitioned by
KEY and which use any storage engine other
than NDB must be dumped and
reloaded.
Same storage engine for all partitions. All partitions of a partitioned table must use the same storage engine and it must be the same storage engine used by the table as a whole. In addition, if one does not specify an engine on the table level, then one must do either of the following when creating or altering a partitioned table:
Do not specify any engine for any partition or subpartition
Specify the engine for all partitions or subpartitions
This section discusses limitations in MySQL Partitioning relating specifically to functions used in partitioning expressions.
Only the MySQL functions shown in the following table are allowed in partitioning expressions.
ABS() | CEILING() (see
CEILING() and FLOOR()) | DAY() |
DAYOFMONTH() | DAYOFWEEK() | DAYOFYEAR() |
DATEDIFF() | EXTRACT() (see
EXTRACT() function with WEEK specifier) | FLOOR() (see
CEILING() and FLOOR()) |
HOUR() | MICROSECOND() | MINUTE() |
MOD() | MONTH() | QUARTER() |
SECOND() | TIME_TO_SEC() | TO_DAYS() |
TO_SECONDS() | UNIX_TIMESTAMP() (permitted beginning
with MySQL 5.6.1 and fully supported beginning with
MySQL 5.6.3, with
TIMESTAMP columns) | WEEKDAY() |
YEAR() | YEARWEEK() |
In MySQL 5.6, range optimization can be used for
the TO_DAYS(),
TO_SECONDS(), and
YEAR() functions. In addition,
beginning with MySQL 5.6.3,
UNIX_TIMESTAMP() is treated as
monotonic in partitioning expressions. See
Chapter 5, Partition Pruning, for more information.
CEILING() and FLOOR().
Each of these functions returns an integer only if it is
passed an argument of an exact numeric type, such as one of
the INT types or
DECIMAL. This means, for
example, that the following CREATE
TABLE statement fails with an error, as shown here:
mysql>CREATE TABLE t (c FLOAT) PARTITION BY LIST( FLOOR(c) )(->PARTITION p0 VALUES IN (1,3,5),->PARTITION p1 VALUES IN (2,4,6)->);ERROR 1490 (HY000): The PARTITION function returns the wrong type
EXTRACT() function with WEEK specifier.
The value returned by the
EXTRACT() function, when used
as EXTRACT(WEEK FROM
, depends on the
value of the
col)default_week_format system
variable. For this reason, beginning with MySQL 5.6.2,
EXTRACT() is no longer
permitted as a partitioning function when it specifies the
unit as WEEK. (Bug #54483)
See Mathematical Functions, for more information about the return types of these functions, as well as Numeric Types.
In MySQL 5.6.5 and earlier, for storage engines such as
MyISAM that actually execute
table-level locks when executing DML or DDL statements, such a
statement affecting a partitioned table imposed a lock on the
table as a whole; that is, all partitions were locked until the
statement was finished. MySQL 5.6.6 implements
partition lock pruning,
which eliminates unneeded locks in many cases. In MySQL 5.6.6
and later, most statements reading from or updating a
partitioned MyISAM table cause only the
effected partitions to be locked. For example, prior to MySQL
5.6.6, a SELECT from a
partitioned MyISAM table caused a lock on the
entire table; in MySQL 5.6.6 and later, only those partitions
actually containing rows that satisfy the
SELECT statement's
WHERE condition are locked. This has the
effect of increasing the speed and efficiency of concurrent
operations on partitioned MyISAM tables. This
improvement becomes particularly noticeable when working with
MyISAM tables that have many (32 or more)
partitions.
This change in behavior does not have any impact on statements
effecting partitioned tables using storage engines such as
InnoDB, that employ row-level
locking and do not actually perform (or need to perform) the
locks prior to partition pruning.
The next few paragraphs discuss the effects of partition lock pruning for various MySQL statements on tables using storage engines that employ table-level locks.
SELECT statements (including
those containing unions or joins) now lock only those partitions
that actually need to be read. This also applies to
SELECT ... PARTITION.
An UPDATE prunes locks only for
tables on which no partitioning columns are updated.
REPLACE and
INSERT now lock only those
partitions having rows to be inserted or replaced. However, if
an AUTO_INCREMENT value is generated for any
partitioning column then all partitions are locked.
INSERT ...
ON DUPLICATE KEY UPDATE is pruned as long as no
partitioning column is updated.
INSERT ...
SELECT now locks only those partitions in the source
table that need to be read, although all partitions in the
target table are locked.
INSERT
DELAYED is not supported for partitioned tables.
Locks imposed by LOAD
DATA statements on partitioned tables cannot be
pruned.
The presence of BEFORE INSERT or
BEFORE UPDATE triggers using any partitioning
column of a partitioned table means that locks on
INSERT and UPDATE
statements updating this table cannot be pruned, since the
trigger can alter its values: A BEFORE INSERT
trigger on any of the table's partitioning columns means
that locks set by INSERT or
REPLACE cannot be pruned, since the
BEFORE INSERT trigger may change a row's
partitioning columns before the row is inserted, forcing the row
into a different partition than it would be otherwise. A
BEFORE UPDATE trigger on a partitioning
column means that locks imposed by UPDATE or
INSERT ... ON DUPLICATE KEY UPDATE cannot be
pruned.
CREATE VIEW no longer causes any
locks.
ALTER
TABLE ... EXCHANGE PARTITION now prunes locks; only
the exchanged table and the exchanged partition are locked.
ALTER
TABLE ... TRUNCATE PARTITION now prunes locks; only
the partitions to be emptied are locked.
ALTER TABLE statements still take
metadata locks on the table level.
LOCK TABLES cannot prune
partition locks.
CALL
stored_procedure(
supports lock pruning, but evaluating
expr)expr does not.
DO and
SET
statements do not support partitioning lock pruning.