концепції / 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).
Розібрано у відео
- Як працюють індекси в базах на прикладі: MySQL vs Postgres, UUID vs Auto Increment
вичерпний бенчмарк: цифри роздування таблиці й індексів, сповільнення вставок, чому Postgres байдуже, і рецепт «auto-increment плюс окрема колонка з UUID»
- Питання та відповіді №1: чи захистить HTTPS?
продовження про зберігання в BINARY(16): помірна економія, гірша ергономіка
- Як працює повнотекстовий пошук, частина 2: запитання-відповіді й подальші оптимізації
UUID як ідентифікатори документів не піддаються дельта-стисненню; прихований FTS_DOC_ID в InnoDB — той самий трюк із мапінгом на цілі числа
- Як працює Base64 і навіщо він потрібен
побічна демонстрація: hex-закодовані UUID, збережені як сирі байти, зменшуються вдвічі
Повʼязане
Індекси баз даних — вибір PK відлунює в кожному індексі таблиці B-tree / B+ tree — порядок вставки проти кешування вузлів — механізм цього сповільнення Стиснення індексу — відсортовані цілі числа стискаються; випадкові UUID — ні MVCC (багатоверсійне керування конкурентним доступом) — друга велика відмінність у внутрішній будові MySQL і Postgres з того самого відео