在INSERT中,InnoDB延迟了二级指标的建立。例如,
CREATE TABLE item_creators
(
item_id int(11) unsigned NOT NULL,
creator_id int(11) unsigned NOT NULL,
INDEX(creator_id),
PRIMARY KEY(item_id)
) ENGINE=InnoDB在第一次查询之后,
INSERT INTO item_creators (item_id,creator_id)
SELECT item_id,creator_id FROM t1;
SELECT a.item_id, b.creator FROM
item_creators a JOIN creators ON a.creator_id=b.creator_id;InnoDB开始重建次要索引,后台为INDEX(creator_id)。如果没有这个索引,第二个查询就会非常慢。
InnoDB重建辅助索引?请注意,它大约是非常大的表(数亿行),在这些表中,索引的构建需要时间。
发布于 2022-08-02 19:41:46
我觉得你有些误会。当您插入一行时,InnoDB不会重建整个索引。它只是在现有索引中添加了一个条目。如果每次插入后必须在大型表上重新构建索引,对性能将是极其不利的。
另一个误解是关于延迟的索引更新。在这段时间内,索引仍然可用。InnoDB知道如何检查change缓冲区中的条目以及索引。如果查询从change缓冲区读取值,则会立即将其合并到索引中。如果查询读取已合并到索引中的其他值,则索引将帮助该查询。
你可能在试图解决一个不存在的问题。
至于你问的问题,如何判断索引是否完全合并,这是很难做到的。您可以查询到有多少缓冲池分配给变更缓冲区(这在手册页:https://dev.mysql.com/doc/refman/8.0/en/innodb-change-buffer.html中有记录)。
SELECT (SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
WHERE PAGE_TYPE LIKE 'IBUF%') AS change_buffer_pages,
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE) AS total_pages,
(SELECT ((change_buffer_pages/total_pages)*100))
AS change_buffer_page_percentage;
+---------------------+-------------+-------------------------------+
| change_buffer_pages | total_pages | change_buffer_page_percentage |
+---------------------+-------------+-------------------------------+
| 2064 | 8191 | 25.1984 |
+---------------------+-------------+-------------------------------+这显示,在我将几百万行插入测试表后,大约25%的缓冲池被等待合并的更改缓冲区内容占用。但它并没有告诉我哪个表或指数,所以可能是其他表(S)的变化才能解释这一点。
随着时间的推移,随着索引更改合并和其他INSERT/UPDATE/DELETE通信量的增加,更改缓冲区页将不断增长和缩小。
发布于 2022-08-02 03:33:03
大插入后的I/O活动可能来自延迟的“更改缓冲区”活动。
这是更新非唯一辅助索引的地方。
这样想吧。在更新/插入/删除一行时,
所以,是的,很多I/O活动。但它的存在是为了提高系统的效率,从而减少I/O。
我认为只有两个设置可以控制更改缓冲区:
innodb_change_buffer_max_size。innodb_change_buffering = all (默认值)没有必要“等待”它的完成;所有这些都是在后台透明地处理的。
发布于 2022-08-02 08:38:11
按照OPTIMIZE TABLE TBL_NAME手册中的建议,在很少的间隔内执行MySQL。
另外,如果item_id和creator_id的组合是唯一的,那么创建一个复合主键。
https://dba.stackexchange.com/questions/315116
复制相似问题