Віктор Турський про програмування / навігатор

концепції / uuid-vs-auto-increment

UUID проти auto-increment у первинних ключах

Одне з найкраще виміряних тверджень каналу: випадкові UUID як первинні ключі катастрофічні в MySQL, але майже нешкідливі в Postgres — бо в MySQL сама таблиця є кластеризованим B+-деревом, відсортованим за PK, і кожен вторинний індекс містить PK усередині. Його цифри на 16 млн рядків: перехід на UUID PK роздуває таблицю з 4.3 GB до 7.8 GB, а вторинні індекси — з 2 GB до 5.5 GB (~70% байтів індексів — це просто первинний ключ); вставки сповільнюються з 4 с до 5.5 с на 1000 рядків на найшвидшому SSD і у 2.5–3 рази на повільніших дисках, бо випадкові UUID вбивають кешування вузлів B+-дерева, тоді як послідовні ID торкаються лише закешованих крайніх правих вузлів. Postgres, з heap-таблицями та фізичними покажчиками на рядки, майже невразливий. Бонусна дрібниця: якщо не вказати PK, MySQL все одно мовчки додасть прихований 6-байтовий (індекси: MySQL проти Postgres).

Його контрінтуїтивний рецепт: не обирати — лишити auto-increment PK для рушія, а UUID зберігати додатковою колонкою для зовнішнього світу; це менше і швидше за будь-який із «чистих» варіантів. Зберігання UUID як BINARY(16) замість 32-символьного тексту допомагає лише помірно (частка первинного ключа в індексах падає з ~70% до ~55%) і робить їх незручними для читання й відображення, тож він усе одно обрав би окрему колонку (Q&A №1). Та сама проблема виринає в повнотекстовому пошуку: UUID як ідентифікатори документів повністю вбивають стиснення posting-списків, тож їх мапують на цілі числа — саме це MySQL/InnoDB FULLTEXT і робить усередині зі своєю прихованою auto-increment колонкою FTS_DOC_ID (повнотекстовий пошук, частина 2).

Розібрано у відео

Повʼязане

Індекси баз даних — вибір PK відлунює в кожному індексі таблиці B-tree / B+ tree — порядок вставки проти кешування вузлів — механізм цього сповільнення Стиснення індексу — відсортовані цілі числа стискаються; випадкові UUID — ні MVCC (багатоверсійне керування конкурентним доступом) — друга велика відмінність у внутрішній будові MySQL і Postgres з того самого відео