排序索引構(gòu)建(Sorted Index Builds)

本文翻譯自MySQL 8.0 Reference Manual 15.6.2.3 Sorted Index Builds

MySQL在創(chuàng)建或者重建索引時(shí),采用的是批量加載并創(chuàng)建索引的方式,而不是每次加載一條數(shù)據(jù)然后插入一條索引的方式。這種批量創(chuàng)建索引的方式被稱為排序索引構(gòu)建(Sorted Index Builds)。排序索引構(gòu)建不支持空間索引(Spatial Indexes)。

采用排序索引構(gòu)建創(chuàng)建索引分為三個(gè)階段。在第一個(gè)階段,通過(guò)掃描聚簇索引產(chǎn)生需要構(gòu)建索引的索引項(xiàng)并放到排序緩沖區(qū)中。當(dāng)排序緩沖區(qū)滿時(shí),這些索引項(xiàng)會(huì)被排序并且寫(xiě)入到一個(gè)臨時(shí)文件中。這步處理也被稱為run。在第二個(gè)階段,當(dāng)一個(gè)或多個(gè)runs被寫(xiě)入臨時(shí)文件,會(huì)對(duì)這些臨時(shí)中的所有索引項(xiàng)進(jìn)行合并排序。在第三個(gè)階段,也即最終階段,這些排過(guò)序的索引項(xiàng)會(huì)被插入到B-tree中。

在引入排序索引構(gòu)建之前,索引項(xiàng)插入到B-tree的插入動(dòng)作時(shí)通過(guò)特定的插入APIs一條記錄一條記錄依次插入的。這種方式首先通過(guò)樂(lè)觀的方式打開(kāi)B-tree索引游標(biāo),找到插入的位置,然后向找到的B-tree索引頁(yè)插入一條記錄。如果因?yàn)轫?yè)滿造成插入失敗,則轉(zhuǎn)為悲觀插入方式,即打開(kāi)B-tree索引游標(biāo),對(duì)頁(yè)進(jìn)行拆分然后進(jìn)行插入動(dòng)作。這種從上向下(top-down)的方式建立索引的代價(jià)就是插入位置的查找以及B-tree節(jié)點(diǎn)的拆分和合并。

排序索引構(gòu)建則采用從下向上的方式構(gòu)建索引。通過(guò)采用這種方式,可以使用持有最后葉子節(jié)點(diǎn)頁(yè),并且可以按需進(jìn)行最右葉子節(jié)點(diǎn)頁(yè)的分配和索引項(xiàng)插入。當(dāng)一個(gè)葉節(jié)點(diǎn)頁(yè)滿時(shí),會(huì)分配一個(gè)新的兄弟頁(yè),然后在其父節(jié)點(diǎn)插入一個(gè)指針指向新分配的兄弟頁(yè)。這個(gè)過(guò)程將一直重復(fù)知道所有的索引項(xiàng)插入完畢。當(dāng)一個(gè)兄弟頁(yè)分配后,指向原先葉子節(jié)點(diǎn)頁(yè)的引用將釋放,新分配的兄弟頁(yè)則成為新的最右節(jié)點(diǎn)頁(yè)并作為新的默認(rèn)插入位置(譯者注:通過(guò)這種方式避免了插入位置的查找)。

  • 為后續(xù)修改或新增數(shù)據(jù)保留一定的B-tree節(jié)點(diǎn)頁(yè)空間

為了在每個(gè)頁(yè)保留一定的頁(yè)空間為后續(xù)可能存在的插入和修改操作做準(zhǔn)備,可以通過(guò)innodb_fill_factor參數(shù)配置需要保留B-tree頁(yè)空間的百分比。例如,設(shè)置innodb_fill_factor=80,則會(huì)在排序構(gòu)建索引時(shí)保留20%的空間為后續(xù)使用做準(zhǔn)備。這個(gè)設(shè)置會(huì)同時(shí)對(duì)B-tree的葉子節(jié)點(diǎn)和非葉子節(jié)點(diǎn)生效。但是對(duì)TEXTBLOB類型的外部頁(yè)不生效。需要注意的是程序?qū)嶋H實(shí)現(xiàn)時(shí)保留的空間并不是嚴(yán)格等于參數(shù)innodb_fill_factor設(shè)置的值,該參數(shù)設(shè)置的值只是一個(gè)參考值并不是一個(gè)硬標(biāo)準(zhǔn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。