Mysql

MySQL Innodb,為什麼主索引的大小取決於記錄的插入順序

  • April 17, 2022

我有一個具有此架構的表

CREATE TABLE `UserIdPhoneNo` (
`userId` int NOT NULL,
`phoneNo` bigint NOT NULL,
PRIMARY KEY (`userId`,`phoneNo`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3

我打算在這個表中儲存 10 億行。查詢主要是讀取,很少寫入。為了使讀取更快,我將為 innodb_buffer_pool 提供足夠的記憶體,以便整個索引適合記憶體。我創建了一個數據集,即 10 億條記錄按這樣的遞增順序

1,263
1,264
1,265
2,266
2,267
2,268

我將此數據載入到此表中。索引大小為 30 GB。現在我使用帶有 -R 選項的排序命令對這些數據進行了混洗,再次插入了這些數據(在插入這些數據之前截斷了表),令我驚訝的是索引大小為 48 GB。我使用此查詢來查找索引的大小

select database_name, table_name, index_name, stat_value*@@innodb_page_size from mysql.innodb_index_stats where stat_name='size';

為什麼我們有不同大小的索引和完全相同的數據集?我們可以做點什麼來解決它嗎?

當您將預先排序的數據插入到 b-tree 索引中時,葉子頁面將趨向於更密集地填充,因為索引僅在尾端增長。當您插入隨機排序的數據時,新行將被插入到所有位置,可能會導致更多的頁面拆分,從而導致更稀疏的結果。

我們可以做點什麼來解決它嗎?

沒有什麼可以“修復”的,所以我就不管它了。您認為將整個表放入記憶體中會顯著提高性能的想法可能是錯誤的。但是,如果您堅持浪費時間,請參閱此問答中的建議,例如。

PRIMARY KEY 與數據“聚集”在一起;一個的大小就是另一個的大小。

我希望“有序”表大約是“隨機”表大小的 69%。

(mustaccio 提供了其餘的解釋。)

引用自:https://dba.stackexchange.com/questions/311049