開發者工具 · UUID 產生器
隨機 UUID 主鍵與 B 樹碎片:到底發生了什麼
· 為什麼它很重要
uuid 密碼學 瀏覽器 API
隨機 v4 鍵插入隨機索引頁,而聚集索引為此付出了代價。這篇文章解釋了這個機制、文字與二元的儲存成本,以及按時間排序的 UUID 在哪些方面改變了情況。
隨著表格的增長,插入速度變慢——這是 DBA 需要考慮他們的關鍵選擇的症狀
在具有聚集索引的資料庫中插入以隨機 UUID 作為主鍵的行會導致資料庫在 B 樹結構內的隨機位置插入新行。順序鍵附加到最右邊的葉頁,將所有插入保留在一個小的快取駐留區域內。隨機鍵將插入分散到整個索引中,迫使資料庫遍歷並修改實體儲存中相距較遠的頁面。隨著表格的成長和樹的加深,每次插入都會涉及更多的頁面並導致更多的 I/O 操作。在一千行時看似便宜的操作在百萬行時變得昂貴。這不是一個理論問題;而是一個問題。它表現為插入吞吐量的可測量下降。
叢集 B 樹如何填入 — 順序鍵附加到最後一頁;隨機鍵觸碰整個索引中的頁面
此機制是 B 樹運作原理的基礎,因為它們在葉頁中維護排序的鍵順序。當您將帶有鍵 10,001 的行插入到已儲存鍵 1 到 10,000 的表中時,資料庫知道該行所屬的位置:在末尾,在現有的最右側頁(如果有空間)中,或在附加空間到右側的新頁面中。當您將具有隨機 UUID (如 7524fae2-7dec-11d0-a765-00a0c91e6bf6)的行插入到同一個表中時,資料庫必須導航樹以查找包含該 UUID 內的鍵頁的確切頁葉,並找到插入該行內的鍵的確切位置並在該行內找到該行。如果該頁面已滿,它將分裂,將其一半內容移至新頁面並更新父節點。
頁面分割和快取壓力 - 為什麼隨機插入成本更高 I/O 以及為什麼效果隨著表大小而增加
隨機鍵建立最壞情況的插入模式,因為每個插入都會落在樹中的隨機位置,而不是附加到最右邊的頁面。資料庫必須搜尋正確的頁面,這通常需要多次頁面讀取——樹的每一層一次。然後它必須修改該頁面,這可能會觸發沿著樹向上傳播的分裂。更多頁面被修改,更多寫入發生,並記憶體緩衝池填充來自樹的不同區域的頁面,而不是專注於活動插入點。快取未命中增加,I/O 成為瓶頸,隨著表格規模增加,插入率趨於穩定。
文字或二進位 — 36 字串與 16 位元組本機 uuid 或二進位 (16) 欄位以及對索引大小的影響
不同資料庫引擎的成本並不統一,因為不同的系統最佳化頁面管理的方式不同。具有積極壓縮、小頁面大小或記憶體操作的資料庫可能會顯示順序鍵和隨機鍵之間較小的效能差異。具有大頁面、機械磁碟或嚴格記憶體限制的資料庫將表現出急劇的效能下降。此問題是可觀察和可測量的:測量 1,000 行、100,000 行和 1,000,000 行的插入率。如果每秒的速率在較大範圍內急劇下降,則您將遇到特定硬體和資料庫配置的隨機插入損失。
按時間排序的替代方案 — UUIDv7 和 ULID 在索引末尾插入時如何保持唯一性
UUID 作為字串使用文字形式的 36 字元或作為二進位 UUID 類型的 16 位元組,取決於所選的儲存格式。 UTF-8 或 ASCII 欄位中的 36 字元字串為 36 位元組,而 64 位元整數為 8 位元組。假設不應用壓縮技術,字串 UUID 欄位上的索引比整數列上的索引大三倍。較大的索引意味著緩衝池中適合的索引頁較少,這意味著遍歷樹時的快取命中較少。適合 RAM 的較小索引比每次查詢時都必須從磁碟讀取的大索引效能更好,無論插入順序或工作負載模式如何。
工作範例 - 為隨機鍵和時間排序鍵表所描述的相同插入工作負載,定性地,沒有發明基準
儲存差異對於主索引和輔助索引都很重要,因為包含主鍵的每個輔助索引都必須儲存完整的 36 字元 UUID 或 16 位元組二進位 UUID 值。這使得二級索引比使用整數鍵進行主鍵查找的索引大得多。複製、備份和查詢結果集都隨著索引大小的增加而按比例增長。 ToolAcre UUID 產生器產生二進位相容的值;與 varchar(36) 相比,根據資料庫將它們儲存為二進位 (16) 或 GUID 類型可以節省空間,並全面提高快取效率。這種儲存優化對於大型系統至關重要。
這不包括什麼-堆組織的表和資料庫,其中主鍵不是聚集的,影響較小
常見的最佳化是將 UUID 在內部儲存為二進制,並僅在 API 或使用者介面需要時將其顯示為字串。索引和連接操作以緊湊的二進位形式進行; API 回應或應用程式程式碼轉換為字串表示形式。某些資料庫提供內建 GUID 或 UUID 類型來自動處理此轉換。其他則需要明確的轉換操作。 36 位元組和 16 位元組列之間的效能差異是真實存在的:具有 100 萬行、36 位元組與 16 位元組 UUID 列鍵的表每個索引等級相差 20 MB,這可能是適合 L3 快取的索引與需要記憶體提取之間的差異。
重點:在選擇版本之前了解您的索引 — ToolAcre 產生器會產生隨機 UUID;使用這篇文章來決定是否適合您的儲存引擎
插入效能、索引大小和查詢特徵之間的權衡需要基於工作負載模式的架構決策。如果字串是升序的(例如基於時間戳記的字串),則順序字串鍵可以快速插入,但會消耗與隨機 UUID 相同的空間並洩漏時間資訊。隨機 UUID 在語意上較乾淨,且沒有可洩漏的時間戳記組件,但插入聚集索引的速度較慢,且整體儲存空間較大。像 UUIDv7 這樣的時間排序替代方案透過保持插入局部性同時避免版本 4 隨機標識符中的時間戳洩漏來結合優點。