← На главную

UUID4 тормозит SQLite в 10 раз, спасает UUID7

05.06.2026 23:13 · hackernews

Использовать UUID в качестве первичного ключа в базах данных — популярная практика, но у неё есть серьёзный недостаток. Случайные UUID4 вставляются в B-дерево в хаотичном порядке, что заставляет базу данных постоянно перестраивать и балансировать индекс. Это приводит к лишним операциям чтения и записи страниц.

Всё сказанное касается не только SQLite, но и любых баз с кластеризованным индексом. В обычной SQLite-таблице есть неявный 64-битный rowid — это и есть кластеризованный индекс. Физический порядок строк совпадает с порядком rowid. Для таблиц WITHOUT ROWID ключом становится явно указанный PRIMARY KEY.

Автор провёл тест: вставлял 10 миллионов строк порциями по миллиону. С обычным целочисленным ключом (INT PRIMARY KEY) скорость держалась около миллиона вставок в секунду — все замеры укладывались в 1069–1208 мс на миллион строк, даже при 100 млн строк.

Потом взяли UUID4 (BLOB PRIMARY KEY, WITHOUT ROWID). Результат — провал. На первом миллионе строк время было 2649 мс, а к 100 миллионам выросло до 12 586 мс. Просадка в 10–12 раз. Профилирование показало красным цветом — огромное время уходит на чтение страниц, запись и балансировку дерева. Из-за случайного порядка вставок B-tree постоянно реорганизуется.

Решение — использовать UUID7. Это версия UUID, упорядоченная по времени. С ней проблема хаоса исчезает. Тесты дали 1245–1372 мс на миллион строк — почти как с INT, хотя blob-ключи занимают 16 байт вместо 8, поэтому небольшое отставание есть.

Вывод: если в SQLite нужен UUID как первичный ключ — берите UUID7. Он ликвидирует главный недостаток случайных идентификаторов и не убивает производительность.

Читать оригинал →