MySQL 8.4 参考手册  /  ...  /  获取有关分区的信息

26.3.5 获取有关分区的信息

本节讨论获取有关现有分区的信息,这可以通过多种方式完成。获取此类信息的方法包括以下几种:

当对分区表进行插入、删除或更新操作时,二进制日志会记录有关该分区以及(如果有)该行事件发生的子分区的信息。即使涉及的表相同,对于发生在不同分区或子分区的修改操作,也会创建新的行事件。因此,如果事务涉及三个分区或子分区,则会生成三个行事件。对于更新事件,分区信息会针对 之前 图像和 之后 图像进行记录。如果您在使用 mysqlbinlog 查看二进制日志时指定了 -v--verbose 选项,则会显示分区信息。只有在使用基于行的日志记录时 (binlog_format=ROW) 才会记录分区信息。

如本章其他地方所述,SHOW CREATE TABLE 的输出中包含用于创建分区表的 PARTITION BY 子句。例如:

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=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
/*!50100 PARTITION BY RANGE (YEAR(purchased))
(PARTITION p0 VALUES LESS THAN (1990) ENGINE = InnoDB,
 PARTITION p1 VALUES LESS THAN (1995) ENGINE = InnoDB,
 PARTITION p2 VALUES LESS THAN (2000) ENGINE = InnoDB,
 PARTITION p3 VALUES LESS THAN (2005) ENGINE = InnoDB) */
0 row in set (0.00 sec)

SHOW TABLE STATUS 对分区表的输出与对非分区表的输出相同,区别在于 Create_options 列包含字符串 partitionedEngine 列包含该表所有分区使用的存储引擎的名称。(有关此语句的更多信息,请参见 第 15.7.7.37 节“SHOW TABLE STATUS 语句”。)

您还可以从 INFORMATION_SCHEMA 中获取有关分区的信息,该模式包含 PARTITIONS 表。请参见 第 28.3.21 节“INFORMATION_SCHEMA PARTITIONS 表”

可以使用 EXPLAIN 判断分区表中哪些分区参与了给定的 SELECT 查询。 EXPLAIN 输出的 partitions 列列出了查询将从中匹配记录的分区。

假设创建一个表 trb1 并填充它,如下所示:

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');

您可以查看在类似于 SELECT * FROM trb1; 的查询中使用了哪些分区,如下所示:

mysql> EXPLAIN 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

在本例中,会搜索所有四个分区。但是,当向查询添加利用分区键的限制条件时,您可以看到仅扫描包含匹配值的那些分区,如下所示:

mysql> EXPLAIN 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 还提供有关使用键和可能键的信息

mysql> ALTER TABLE trb1 ADD PRIMARY KEY (id);
Query OK, 10 rows affected (0.03 sec)
Records: 10  Duplicates: 0  Warnings: 0

mysql> EXPLAIN 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

如果使用 EXPLAIN 检查针对非分区表的查询,则不会产生错误,但 partitions 列的值始终为 NULL

EXPLAIN 输出的 rows 列显示表中的总行数。

另请参见 第 15.8.2 节“EXPLAIN 语句”