Table of Contents
MySQL 5.5 provides a number of ways to modify
partitioned tables. It is possible to add, drop, redefine, merge,
or split existing partitions. All of these actions can be carried
out using the partitioning extensions to the
ALTER
TABLE statement. There are also ways to obtain
information about partitioned tables and partitions. We discuss
these topics in the sections that follow.
For information about partition management in tables
partitioned by RANGE or
LIST, see
Section 4.1, “Management of RANGE and LIST Partitions”.
For a discussion of managing HASH and
KEY partitions, see
Section 4.2, “Management of HASH and KEY Partitions”.
See Section 4.4, “Obtaining Information About Partitions”, for a discussion of mechanisms provided in MySQL 5.5 for obtaining information about partitioned tables and partitions.
For a discussion of performing maintenance operations on partitions, see Section 4.3, “Maintenance of Partitions”.
In MySQL 5.5, all partitions of a partitioned table must have the same number of subpartitions, and it is not possible to change the subpartitioning once the table has been created.
To change a table's partitioning scheme, it is necessary only to
use the
ALTER
TABLE statement with a
partition_options clause. This clause
has the same syntax as that as used with
CREATE TABLE for creating a
partitioned table, and always begins with the keywords
PARTITION BY. Suppose that you have a table
partitioned by range using the following
CREATE TABLE statement:
CREATE TABLE trb3 (id INT, name VARCHAR(50), purchased DATE)
PARTITION BY RANGE( YEAR(purchased) ) (
PARTITION p0 VALUES LESS THAN (1990),
PARTITION p1 VALUES LESS THAN (1995),
PARTITION p2 VALUES LESS THAN (2000),
PARTITION p3 VALUES LESS THAN (2005)
);
To repartition this table so that it is partitioned by key into
two partitions using the id column value as the
basis for the key, you can use this statement:
ALTER TABLE trb3 PARTITION BY KEY(id) PARTITIONS 2;
This has the same effect on the structure of the table as dropping
the table and re-creating it using CREATE TABLE trb3
PARTITION BY KEY(id) PARTITIONS 2;.
ALTER TABLE ... ENGINE = ... changes only the
storage engine used by the table, and leaves the table's
partitioning scheme intact. Use ALTER TABLE ... REMOVE
PARTITIONING to remove a table's partitioning. See
ALTER TABLE Syntax.
Only a single PARTITION BY, ADD
PARTITION, DROP PARTITION,
REORGANIZE PARTITION, or COALESCE
PARTITION clause can be used in a given
ALTER
TABLE statement. If you (for example) wish to drop a
partition and reorganize a table's remaining partitions,
you must do so in two separate
ALTER
TABLE statements (one using DROP
PARTITION and then a second one using
REORGANIZE PARTITIONS).
Beginning with MySQL 5.5.0, it is possible to delete all rows from
one or more selected partitions using
ALTER TABLE ...
TRUNCATE PARTITION.
Range and list partitions are very similar with regard to how
the adding and dropping of partitions are handled. For this
reason we discuss the management of both sorts of partitioning
in this section. For information about working with tables that
are partitioned by hash or key, see
Section 4.2, “Management of HASH and KEY Partitions”. Dropping a
RANGE or LIST partition is
more straightforward than adding one, so we discuss this first.
Dropping a partition from a table that is partitioned by either
RANGE or by LIST can be
accomplished using the
ALTER
TABLE statement with a DROP
PARTITION clause. Here is a very basic example, which
supposes that you have already created a table which is
partitioned by range and then populated with 10 records using
the following CREATE TABLE and
INSERT statements:
mysql>CREATE TABLE tr (id INT, name VARCHAR(50), purchased DATE)->PARTITION BY RANGE( YEAR(purchased) ) (->PARTITION p0 VALUES LESS THAN (1990),->PARTITION p1 VALUES LESS THAN (1995),->PARTITION p2 VALUES LESS THAN (2000),->PARTITION p3 VALUES LESS THAN (2005)->);Query OK, 0 rows affected (0.01 sec) mysql>INSERT INTO tr VALUES->(1, 'desk organiser', '2003-10-15'),->(2, 'CD player', '1993-11-05'),->(3, 'TV set', '1996-03-10'),->(4, 'bookcase', '1982-01-10'),->(5, 'exercise bike', '2004-05-09'),->(6, 'sofa', '1987-06-05'),->(7, 'popcorn maker', '2001-11-22'),->(8, 'aquarium', '1992-08-04'),->(9, 'study desk', '1984-09-16'),->(10, 'lava lamp', '1998-12-25');Query OK, 10 rows affected (0.01 sec)
You can see which items should have been inserted into partition
p2 as shown here:
mysql>SELECT * FROM tr->WHERE purchased BETWEEN '1995-01-01' AND '1999-12-31';+------+-----------+------------+ | id | name | purchased | +------+-----------+------------+ | 3 | TV set | 1996-03-10 | | 10 | lava lamp | 1998-12-25 | +------+-----------+------------+ 2 rows in set (0.00 sec)
To drop the partition named p2, execute the
following command:
mysql> ALTER TABLE tr DROP PARTITION p2;
Query OK, 0 rows affected (0.03 sec)
The NDBCLUSTER storage engine
does not support ALTER TABLE ... DROP
PARTITION. It does, however, support the other
partitioning-related extensions to
ALTER
TABLE that are described in this chapter.
It is very important to remember that, when you drop a
partition, you also delete all the data that was stored in that
partition. You can see that this is the case by
re-running the previous SELECT
query:
mysql>SELECT * FROM tr WHERE purchased->BETWEEN '1995-01-01' AND '1999-12-31';Empty set (0.00 sec)
Because of this, you must have the
DROP privilege for a table before
you can execute ALTER TABLE ... DROP
PARTITION on that table.
If you wish to drop all data from all partitions while
preserving the table definition and its partitioning scheme, use
the TRUNCATE TABLE statement.
(See TRUNCATE TABLE Syntax.)
If you intend to change the partitioning of a table
without losing data, use ALTER
TABLE ... REORGANIZE PARTITION instead. See below or
in ALTER TABLE Syntax, for information about
REORGANIZE PARTITION.
If you now execute a SHOW CREATE
TABLE statement, you can see how the partitioning
makeup of the table has been changed:
mysql> SHOW CREATE TABLE tr\G
*************************** 1. row ***************************
Table: tr
Create Table: CREATE TABLE `tr` (
`id` int(11) default NULL,
`name` varchar(50) default NULL,
`purchased` date default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
PARTITION BY RANGE ( YEAR(purchased) ) (
PARTITION p0 VALUES LESS THAN (1990) ENGINE = MyISAM,
PARTITION p1 VALUES LESS THAN (1995) ENGINE = MyISAM,
PARTITION p3 VALUES LESS THAN (2005) ENGINE = MyISAM
)
1 row in set (0.01 sec)
When you insert new rows into the changed table with
purchased column values between
'1995-01-01' and
'2004-12-31' inclusive, those rows will be
stored in partition p3. You can verify this
as follows:
mysql>INSERT INTO tr VALUES (11, 'pencil holder', '1995-07-12');Query OK, 1 row affected (0.00 sec) mysql>SELECT * FROM tr WHERE purchased->BETWEEN '1995-01-01' AND '2004-12-31';+------+----------------+------------+ | id | name | purchased | +------+----------------+------------+ | 11 | pencil holder | 1995-07-12 | | 1 | desk organiser | 2003-10-15 | | 5 | exercise bike | 2004-05-09 | | 7 | popcorn maker | 2001-11-22 | +------+----------------+------------+ 4 rows in set (0.00 sec) mysql>ALTER TABLE tr DROP PARTITION p3;Query OK, 0 rows affected (0.03 sec) mysql>SELECT * FROM tr WHERE purchased->BETWEEN '1995-01-01' AND '2004-12-31';Empty set (0.00 sec)
Note that the number of rows dropped from the table as a result
of ALTER TABLE ... DROP PARTITION is not
reported by the server as it would be by the equivalent
DELETE query.
Dropping LIST partitions uses exactly the
same ALTER TABLE ... DROP PARTITION syntax as
used for dropping RANGE partitions. However,
there is one important difference in the effect this has on your
use of the table afterward: You can no longer insert into the
table any rows having any of the values that were included in
the value list defining the deleted partition. (See
Section 3.2, “LIST Partitioning”, for an example.)
To add a new range or list partition to a previously partitioned
table, use the ALTER TABLE ... ADD PARTITION
statement. For tables which are partitioned by
RANGE, this can be used to add a new range to
the end of the list of existing partitions. Suppose that you
have a partitioned table containing membership data for your
organization, which is defined as follows:
CREATE TABLE members (
id INT,
fname VARCHAR(25),
lname VARCHAR(25),
dob DATE
)
PARTITION BY RANGE( YEAR(dob) ) (
PARTITION p0 VALUES LESS THAN (1970),
PARTITION p1 VALUES LESS THAN (1980),
PARTITION p2 VALUES LESS THAN (1990)
);
Suppose further that the minimum age for members is 16. As the
calendar approaches the end of 2005, you realize that you will
soon be admitting members who were born in 1990 (and later in
years to come). You can modify the members
table to accommodate new members born in the years 1990 to 1999
as shown here:
ALTER TABLE members ADD PARTITION (PARTITION p3 VALUES LESS THAN (2000));
With tables that are partitioned by range, you can use
ADD PARTITION to add new partitions to the
high end of the partitions list only. Trying to add a new
partition in this manner between or before existing partitions
results in an error as shown here:
mysql>ALTER TABLE members>ADD PARTITION (>PARTITION n VALUES LESS THAN (1960));ERROR 1463 (HY000): VALUES LESS THAN value must be strictly » increasing for each partition
You can work around this problem by reorganizing the first partition into two new ones that split the range between them, like this:
ALTER TABLE members
REORGANIZE PARTITION p0 INTO (
PARTITION n0 VALUES LESS THAN (1960),
PARTITION n1 VALUES LESS THAN (1970)
);
Using SHOW CREATE TABLE you can
see that the ALTER TABLE statement has had
the desired effect:
mysql> SHOW CREATE TABLE members\G
*************************** 1. row ***************************
Table: members
Create Table: CREATE TABLE `members` (
`id` int(11) DEFAULT NULL,
`fname` varchar(25) DEFAULT NULL,
`lname` varchar(25) DEFAULT NULL,
`dob` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE ( YEAR(dob))
(PARTITION n0 VALUES LESS THAN (1960) ENGINE = InnoDB,
PARTITION n1 VALUES LESS THAN (1970) ENGINE = InnoDB,
PARTITION p1 VALUES LESS THAN (1980) ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (1990) ENGINE = InnoDB,
PARTITION p3 VALUES LESS THAN (2000) ENGINE = InnoDB) */
1 row in set (0.00 sec)
See also ALTER TABLE Partition Operations.
You can also use ALTER TABLE ... ADD
PARTITION to add new partitions to a table that is
partitioned by LIST. Suppose a table
tt is defined using the following
CREATE TABLE statement:
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)
);
You can add a new partition in which to store rows having the
data column values 7,
14, and 21 as shown:
ALTER TABLE tt ADD PARTITION (PARTITION p2 VALUES IN (7, 14, 21));
Note that you cannot add a new
LIST partition encompassing any values that
are already included in the value list of an existing partition.
If you attempt to do so, an error will result:
mysql>ALTER TABLE tt ADD PARTITION>(PARTITION np VALUES IN (4, 8, 12));ERROR 1465 (HY000): Multiple definition of same constant » in list partitioning
Because any rows with the data column value
12 have already been assigned to partition
p1, you cannot create a new partition on
table tt that includes 12
in its value list. To accomplish this, you could drop
p1, and add np and then a
new p1 with a modified definition. However,
as discussed earlier, this would result in the loss of all data
stored in p1—and it is often the case
that this is not what you really want to do. Another solution
might appear to be to make a copy of the table with the new
partitioning and to copy the data into it using
CREATE TABLE ...
SELECT ..., then drop the old table and rename the new
one, but this could be very time-consuming when dealing with a
large amounts of data. This also might not be feasible in
situations where high availability is a requirement.
You can add multiple partitions in a single ALTER TABLE
... ADD PARTITION statement as shown here:
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(50) NOT NULL,
lname VARCHAR(50) NOT NULL,
hired DATE NOT NULL
)
PARTITION BY RANGE( YEAR(hired) ) (
PARTITION p1 VALUES LESS THAN (1991),
PARTITION p2 VALUES LESS THAN (1996),
PARTITION p3 VALUES LESS THAN (2001),
PARTITION p4 VALUES LESS THAN (2005)
);
ALTER TABLE employees ADD PARTITION (
PARTITION p5 VALUES LESS THAN (2010),
PARTITION p6 VALUES LESS THAN MAXVALUE
);
Fortunately, MySQL's partitioning implementation provides ways
to redefine partitions without losing data. Let us look first at
a couple of simple examples involving RANGE
partitioning. Recall the members table which
is now defined as shown here:
mysql> SHOW CREATE TABLE members\G
*************************** 1. row ***************************
Table: members
Create Table: CREATE TABLE `members` (
`id` int(11) default NULL,
`fname` varchar(25) default NULL,
`lname` varchar(25) default NULL,
`dob` date default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
PARTITION BY RANGE ( YEAR(dob) ) (
PARTITION p0 VALUES LESS THAN (1970) ENGINE = MyISAM,
PARTITION p1 VALUES LESS THAN (1980) ENGINE = MyISAM,
PARTITION p2 VALUES LESS THAN (1990) ENGINE = MyISAM.
PARTITION p3 VALUES LESS THAN (2000) ENGINE = MyISAM
)
Suppose that you would like to move all rows representing
members born before 1960 into a separate partition. As we have
already seen, this cannot be done using
ALTER
TABLE ... ADD PARTITION. However, you can use another
partition-related extension to
ALTER
TABLE to accomplish this:
ALTER TABLE members REORGANIZE PARTITION p0 INTO (
PARTITION s0 VALUES LESS THAN (1960),
PARTITION s1 VALUES LESS THAN (1970)
);
In effect, this command splits partition p0
into two new partitions s0 and
s1. It also moves the data that was stored in
p0 into the new partitions according to the
rules embodied in the two PARTITION ... VALUES
... clauses, so that s0 contains
only those records for which
YEAR(dob) is less than 1960 and
s1 contains those rows in which
YEAR(dob) is greater than or
equal to 1960 but less than 1970.
A REORGANIZE PARTITION clause may also be
used for merging adjacent partitions. You can return the
members table to its previous partitioning as
shown here:
ALTER TABLE members REORGANIZE PARTITION s0,s1 INTO (
PARTITION p0 VALUES LESS THAN (1970)
);
No data is lost in splitting or merging partitions using
REORGANIZE PARTITION. In executing the above
statement, MySQL moves all of the records that were stored in
partitions s0 and s1 into
partition p0.
The general syntax for REORGANIZE PARTITION
is shown here:
ALTER TABLEtbl_nameREORGANIZE PARTITIONpartition_listINTO (partition_definitions);
Here, tbl_name is the name of the
partitioned table, and partition_list
is a comma-separated list of names of one or more existing
partitions to be changed.
partition_definitions is a
comma-separated list of new partition definitions, which follow
the same rules as for the
partition_definitions list used in
CREATE TABLE (see
CREATE TABLE Syntax). It should be noted that you are
not limited to merging several partitions into one, or to
splitting one partition into many, when using
REORGANIZE PARTITION. For example, you can
reorganize all four partitions of the members
table into two, as follows:
ALTER TABLE members REORGANIZE PARTITION p0,p1,p2,p3 INTO (
PARTITION m0 VALUES LESS THAN (1980),
PARTITION m1 VALUES LESS THAN (2000)
);
You can also use REORGANIZE PARTITION with
tables that are partitioned by LIST. Let us
return to the problem of adding a new partition to the
list-partitioned tt table and failing because
the new partition had a value that was already present in the
value-list of one of the existing partitions. We can handle this
by adding a partition that contains only nonconflicting values,
and then reorganizing the new partition and the existing one so
that the value which was stored in the existing one is now moved
to the new one:
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)
);
Here are some key points to keep in mind when using
ALTER TABLE ... REORGANIZE PARTITION to
repartition tables that are partitioned by
RANGE or LIST:
The PARTITION clauses used to determine
the new partitioning scheme are subject to the same rules as
those used with a CREATE
TABLE statement.
Most importantly, you should remember that the new
partitioning scheme cannot have any overlapping ranges
(applies to tables partitioned by RANGE)
or sets of values (when reorganizing tables partitioned by
LIST).
The combination of partitions in the
partition_definitions list should
account for the same range or set of values overall as the
combined partitions named in the
partition_list.
For instance, in the members table used
as an example in this section, partitions
p1 and p2 together
cover the years 1980 through 1999. Therefore, any
reorganization of these two partitions should cover the same
range of years overall.
For tables partitioned by RANGE, you can
reorganize only adjacent partitions; you cannot skip over
range partitions.
For instance, you could not reorganize the
members table used as an example in this
section using a statement beginning with ALTER
TABLE members REORGANIZE PARTITION p0,p2 INTO ...
because p0 covers the years prior to 1970
and p2 the years from 1990 through 1999
inclusive, and thus the two are not adjacent partitions.
You cannot use REORGANIZE PARTITION to
change the table's partitioning type; that is, you cannot
(for example) change RANGE partitions to
HASH partitions or vice
versa. You also cannot use this command to
change the partitioning expression or column. To accomplish
either of these tasks without dropping and re-creating the
table, you can use
ALTER
TABLE ... PARTITION BY .... For example:
ALTER TABLE members
PARTITION BY HASH( YEAR(dob) )
PARTITIONS 8;
Tables which are partitioned by hash or by key are very similar to one another with regard to making changes in a partitioning setup, and both differ in a number of ways from tables which have been partitioned by range or list. For that reason, this section addresses the modification of tables partitioned by hash or by key only. For a discussion of adding and dropping of partitions of tables that are partitioned by range or list, see Section 4.1, “Management of RANGE and LIST Partitions”.
You cannot drop partitions from tables that are partitioned by
HASH or KEY in the same
way that you can from tables that are partitioned by
RANGE or LIST. However,
you can merge HASH or KEY
partitions using the ALTER TABLE ... COALESCE
PARTITION statement. Suppose that you have a table
containing data about clients, which is divided into twelve
partitions. The clients table is defined as
shown here:
CREATE TABLE clients (
id INT,
fname VARCHAR(30),
lname VARCHAR(30),
signed DATE
)
PARTITION BY HASH( MONTH(signed) )
PARTITIONS 12;
To reduce the number of partitions from twelve to eight, execute
the following
ALTER
TABLE command:
mysql> ALTER TABLE clients COALESCE PARTITION 4;
Query OK, 0 rows affected (0.02 sec)
COALESCE works equally well with tables that
are partitioned by HASH,
KEY, LINEAR HASH, or
LINEAR KEY. Here is an example similar to the
previous one, differing only in that the table is partitioned by
LINEAR KEY:
mysql>CREATE TABLE clients_lk (->id INT,->fname VARCHAR(30),->lname VARCHAR(30),->signed DATE->)->PARTITION BY LINEAR KEY(signed)->PARTITIONS 12;Query OK, 0 rows affected (0.03 sec) mysql>ALTER TABLE clients_lk COALESCE PARTITION 4;Query OK, 0 rows affected (0.06 sec) Records: 0 Duplicates: 0 Warnings: 0
Note that the number following COALESCE
PARTITION is the number of partitions to merge into
the remainder—in other words, it is the number of
partitions to remove from the table.
If you attempt to remove more partitions than the table has, the result is an error like the one shown:
mysql> ALTER TABLE clients COALESCE PARTITION 18;
ERROR 1478 (HY000): Cannot remove all partitions, use DROP TABLE instead
To increase the number of partitions for the
clients table from 12 to 18. use
ALTER TABLE ... ADD PARTITION as shown here:
ALTER TABLE clients ADD PARTITION PARTITIONS 6;
A number of table and partition maintenance tasks can be carried out using SQL statements intended for such purposes on partitioned tables in MySQL 5.5.
Table maintenance of partitioned tables can be accomplished
using the statements CHECK TABLE,
OPTIMIZE TABLE,
ANALYZE TABLE, and
REPAIR TABLE, which are supported
for partitioned tables.
You can use a number of extensions to
ALTER
TABLE for performing operations of this type on one or
more partitions directly, as described in the following list:
Rebuilding partitions. Rebuilds the partition; this has the same effect as dropping all records stored in the partition, then reinserting them. This can be useful for purposes of defragmentation.
Example:
ALTER TABLE t1 REBUILD PARTITION p0, p1;
Optimizing partitions.
If you have deleted a large number of rows from a
partition or if you have made many changes to a
partitioned table with variable-length rows (that is,
having VARCHAR,
BLOB, or
TEXT columns), you can use
ALTER
TABLE ... OPTIMIZE PARTITION to reclaim any
unused space and to defragment the partition data file.
Example:
ALTER TABLE t1 OPTIMIZE PARTITION p0, p1;
Using OPTIMIZE PARTITION on a given
partition is equivalent to running CHECK
PARTITION, ANALYZE PARTITION,
and REPAIR PARTITION on that partition.
Some MySQL storage engines, including
InnoDB, do not support
per-partition optimization; in these cases,
ALTER
TABLE ... OPTIMIZE PARTITION rebuilds the entire
table. In MySQL 5.5.30 and later, running this statement on
such a table causes the entire table to rebuilt and
analyzed, and an appropriate warning to be issued. (Bug
#11751825, Bug #42822) Use ALTER TABLE ... REBUILD
PARTITION and ALTER TABLE ... ANALYZE
PARTITION instead, to avoid this issue.
Analyzing partitions. This reads and stores the key distributions for partitions.
Example:
ALTER TABLE t1 ANALYZE PARTITION p3;
Repairing partitions. This repairs corrupted partitions.
Example:
ALTER TABLE t1 REPAIR PARTITION p0,p1;
Checking partitions.
You can check partitions for errors in much the same way
that you can use CHECK
TABLE with nonpartitioned tables.
Example:
ALTER TABLE trb3 CHECK PARTITION p1;
This command will tell you if the data or indexes in
partition p1 of table
t1 are corrupted. If this is the case,
use
ALTER
TABLE ... REPAIR PARTITION to repair the
partition.
Each of the statements in the list just shown also supports the
keyword ALL in place of the list of partition
names. Using ALL causes the statement to act
on all partitions in the table.
The use of mysqlcheck and myisamchk is not supported with partitioned tables.
Beginning with MySQL 5.5.0, you can also truncate partitions
using
ALTER
TABLE ... TRUNCATE PARTITION. This statement can be
used to delete all rows from one or more partitions in much the
same way that TRUNCATE TABLE
deletes all rows from a table.
ALTER TABLE ... TRUNCATE PARTITION ALL
truncates all partitions in the table.
ANALYZE, CHECK,
OPTIMIZE, REBUILD,
REPAIR, and TRUNCATE
operations are not supported for subpartitions.
This section discusses obtaining information about existing partitions, which can be done in a number of ways. Methods of obtaining such information include the following:
Using the SHOW CREATE TABLE
statement to view the partitioning clauses used in creating
a partitioned table.
Using the SHOW TABLE STATUS
statement to determine whether a table is partitioned.
Querying the
INFORMATION_SCHEMA.PARTITIONS
table.
Using the statement
EXPLAIN PARTITIONS
SELECT to see which partitions are used by a given
SELECT.
As discussed elsewhere in this chapter,
SHOW CREATE TABLE includes in its
output the PARTITION BY clause used to create
a partitioned table. For example:
mysql> SHOW CREATE TABLE trb3\G
*************************** 1. row ***************************
Table: trb3
Create Table: CREATE TABLE `trb3` (
`id` int(11) default NULL,
`name` varchar(50) default NULL,
`purchased` date default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
PARTITION BY RANGE (YEAR(purchased)) (
PARTITION p0 VALUES LESS THAN (1990) ENGINE = MyISAM,
PARTITION p1 VALUES LESS THAN (1995) ENGINE = MyISAM,
PARTITION p2 VALUES LESS THAN (2000) ENGINE = MyISAM,
PARTITION p3 VALUES LESS THAN (2005) ENGINE = MyISAM
)
1 row in set (0.00 sec)
The output from SHOW TABLE STATUS
for partitioned tables is the same as that for nonpartitioned
tables, except that the Create_options column
contains the string partitioned. The
Engine column contains the name of the
storage engine used by all partitions of the table. (See
SHOW TABLE STATUS Syntax, for more information about
this statement.)
You can also obtain information about partitions from
INFORMATION_SCHEMA, which contains a
PARTITIONS table. See
The INFORMATION_SCHEMA PARTITIONS Table.
It is possible to determine which partitions of a partitioned
table are involved in a given
SELECT query using
EXPLAIN
PARTITIONS. The PARTITIONS keyword
adds a partitions column to the output of
EXPLAIN listing the partitions
from which records would be matched by the query.
Suppose that you have a table trb1 created
and populated as follows:
CREATE TABLE trb1 (id INT, name VARCHAR(50), purchased DATE)
PARTITION BY RANGE(id)
(
PARTITION p0 VALUES LESS THAN (3),
PARTITION p1 VALUES LESS THAN (7),
PARTITION p2 VALUES LESS THAN (9),
PARTITION p3 VALUES LESS THAN (11)
);
INSERT INTO trb1 VALUES
(1, 'desk organiser', '2003-10-15'),
(2, 'CD player', '1993-11-05'),
(3, 'TV set', '1996-03-10'),
(4, 'bookcase', '1982-01-10'),
(5, 'exercise bike', '2004-05-09'),
(6, 'sofa', '1987-06-05'),
(7, 'popcorn maker', '2001-11-22'),
(8, 'aquarium', '1992-08-04'),
(9, 'study desk', '1984-09-16'),
(10, 'lava lamp', '1998-12-25');
You can see which partitions are used in a query such as
SELECT * FROM trb1;, as shown here:
mysql> EXPLAIN PARTITIONS SELECT * FROM trb1\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: trb1
partitions: p0,p1,p2,p3
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 10
Extra: Using filesort
In this case, all four partitions are searched. However, when a limiting condition making use of the partitioning key is added to the query, you can see that only those partitions containing matching values are scanned, as shown here:
mysql> EXPLAIN PARTITIONS SELECT * FROM trb1 WHERE id < 5\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: trb1
partitions: p0,p1
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 10
Extra: Using where
EXPLAIN
PARTITIONS provides information about keys used and
possible keys, just as with the standard
EXPLAIN
SELECT statement:
mysql>ALTER TABLE trb1 ADD PRIMARY KEY (id);Query OK, 10 rows affected (0.03 sec) Records: 10 Duplicates: 0 Warnings: 0 mysql>EXPLAIN PARTITIONS SELECT * FROM trb1 WHERE id < 5\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: trb1 partitions: p0,p1 type: range possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: NULL rows: 7 Extra: Using where
You should take note of the following restrictions and
limitations on EXPLAIN
PARTITIONS:
You cannot use the PARTITIONS and
EXTENDED keywords together in the same
EXPLAIN ...
SELECT statement. Attempting to do so produces a
syntax error.
If EXPLAIN
PARTITIONS is used to examine a query against a
nonpartitioned table, no error is produced, but the value of
the partitions column is always
NULL.
The rows column of
EXPLAIN
PARTITIONS output displays the total number of rows in
the table.
See also EXPLAIN Syntax.