17.8.11 配置索引页的合并阈值
您可以配置索引页的MERGE_THRESHOLD
值。如果索引页的“page-full”%小于等于MERGE_THRESHOLD
值时,删除或更新操作将尝试合并索引页与邻近索引页。InnoDB
的默认MERGE_THRESHOLD
值为50,这是之前硬编码的值。最小MERGE_THRESHOLD
值为1,最大值为50。
当索引页的“page-full”%小于50%,即默认的MERGE_THRESHOLD
设置时,InnoDB
将尝试合并索引页与邻近页。如果两个页都接近50%满,则可能会在合并后很快出现页分裂行为。频繁的合并-分裂行为可能会对性能产生不良影响。为了避免频繁的合并-分裂行为,您可以降低MERGE_THRESHOLD
值,以便InnoDB
在更低的“page-full”%时尝试合并页。合并页时留下的更多空间可以帮助减少合并-分裂行为。
索引页面的MERGE_THRESHOLD
可以在表或单个索引中定义。对单个索引定义的MERGE_THRESHOLD
值优先于对表的定义。如果未定义,MERGE_THRESHOLD
值默认为50。
可以使用CREATE TABLE
语句的table_option
COMMENT
子句来设置表的MERGE_THRESHOLD
值。例如:
CREATE TABLE t1 (
id INT,
KEY id_index (id)
) COMMENT='MERGE_THRESHOLD=45';
也可以使用ALTER TABLE
语句的table_option
COMMENT
子句来设置已有的表的MERGE_THRESHOLD
值:
CREATE TABLE t1 (
id INT,
KEY id_index (id)
);
ALTER TABLE t1 COMMENT='MERGE_THRESHOLD=40';
Setting MERGE_THRESHOLD for Individual 索引
要为单个索引设置MERGE_THRESHOLD
值,可以使用CREATE TABLE
、ALTER TABLE
或CREATE INDEX
语句的index_option
COMMENT
子句,例如:
-
使用
CREATE TABLE
语句设置单个索引的MERGE_THRESHOLD
值:CREATE TABLE t1 ( id INT, KEY id_index (id) COMMENT 'MERGE_THRESHOLD=40' );
-
使用
ALTER TABLE
设置MERGE_THRESHOLD
索引:CREATE TABLE t1 ( id INT, KEY id_index (id) ); ALTER TABLE t1 DROP KEY id_index; ALTER TABLE t1 ADD KEY id_index (id) COMMENT 'MERGE_THRESHOLD=40';
-
使用
CREATE INDEX
设置MERGE_THRESHOLD
索引:CREATE TABLE t1 (id INT); CREATE INDEX id_index ON t1 (id) COMMENT 'MERGE_THRESHOLD=40';
不能在GEN_CLUST_INDEX
上修改MERGE_THRESHOLD
值,因为这是由InnoDB
创建的聚簇索引。可以通过设置表的MERGE_THRESHOLD
值来修改GEN_CLUST_INDEX
。
可以通过查询INNODB_INDEXES
表来获取当前索引的MERGE_THRESHOLD
值。例如:
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_INDEXES WHERE NAME='id_index' \G
*************************** 1. row ***************************
INDEX_ID: 91
NAME: id_index
TABLE_ID: 68
TYPE: 0
N_FIELDS: 1
PAGE_NO: 4
SPACE: 57
MERGE_THRESHOLD: 40
可以使用SHOW CREATE TABLE
查看表的MERGE_THRESHOLD
值,如果使用COMMENT
子句定义了该值:
mysql> SHOW CREATE TABLE t2 \G
*************************** 1. row ***************************
Table: t2
Create Table: CREATE TABLE `t2` (
`id` int(11) DEFAULT NULL,
KEY `id_index` (`id`) COMMENT 'MERGE_THRESHOLD=40'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
在索引级别定义的MERGE_THRESHOLD
值优先于表级别定义的MERGE_THRESHOLD
值。如果未定义,MERGE_THRESHOLD
默认为50%(MERGE_THRESHOLD=50
),这是之前硬编码的值。
类似地,您可以使用SHOW INDEX
查看索引的MERGE_THRESHOLD
值,如果使用index_option
COMMENT
子句明确定义了该值:
mysql> SHOW INDEX FROM t2 \G
*************************** 1. row ***************************
Table: t2
Non_unique: 1
Key_name: id_index
Seq_in_index: 1
Column_name: id
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment: MERGE_THRESHOLD=40
TheINNODB_METRICS
表提供了两个计数器,可以用来衡量MERGE_THRESHOLD
设置对索引页面合并的影响。
mysql> SELECT NAME, COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS
WHERE NAME like '%index_page_merge%';
+-----------------------------+----------------------------------------+
| NAME | COMMENT |
+-----------------------------+----------------------------------------+
| index_page_merge_attempts | Number of index page merge attempts |
| index_page_merge_successful | Number of successful index page merges |
+-----------------------------+----------------------------------------+
当降低MERGE_THRESHOLD
值时,目标是:
-
少数页面合并尝试和成功页面合并
-
类似数量的页面合并尝试和成功页面合并
MERGE_THRESHOLD
设置太小可能导致大量空白页面空间,导致数据文件过大。
有关使用INNODB_METRICS
计数器的信息,请参阅第17.15.6节,“InnoDB INFORMATION_SCHEMA Metrics Table”。