Чи варто вкласти час, щоб змінити тип стовпця з CHAR (36) на UUID?


14

У мене вже є кілька мільйонів рядків у моїй базі даних. Я не знав про тип даних PostgreSQL UUID, коли розробляв свою схему.

В одній із таблиць є 16М рядків (близько 3,5 млн. До 4 М записів на фрагмент), що зростає приблизно в 500 тис. Записів на день. У мене все ще є розкіш знімати виробничу систему на кілька годин, якщо потрібно. Я не буду мати такої розкоші через один-два тижні.

Моє запитання: чи варто це робити? Мені цікаво про продуктивність JOIN, використання дискового простору (повний дамп gzip'd становить 1,25 ГБ), речі такого характеру.

Схема таблиці є:

# \d twitter_interactions
                Table "public.twitter_interactions"
         Column          |            Type             | Modifiers 
-------------------------+-----------------------------+-----------
 interaction_id          | character(36)               | not null
 status_text             | character varying(1024)     | not null
 screen_name             | character varying(40)       | not null
 twitter_user_id         | bigint                      | 
 replying_to_screen_name | character varying(40)       | 
 source                  | character varying(240)      | not null
 tweet_id                | bigint                      | not null
 created_at              | timestamp without time zone | not null
Indexes:
    "twitter_interactions_pkey" PRIMARY KEY, btree (interaction_id)
    "twitter_interactions_tweet_id_key" UNIQUE, btree (tweet_id)
    "index_twitter_interactions_on_created_at" btree (created_at)
    "index_twitter_interactions_on_screen_name" btree (screen_name)
Triggers:
    insert_twitter_interactions_trigger BEFORE INSERT ON twitter_interactions FOR EACH ROW EXECUTE PROCEDURE twitter_interactions_insert_trigger()
Number of child tables: 9 (Use \d+ to list them.)

Відповіді:


13

Я б розглядав можливість зміни типу UUID. char(36)займає 40 байт, uuidзаймає 16, тож ви заощадите 24 байти на рядок, що для вас прирівнюватиме до 12 МБ на день, 4 ГБ через рік. Плюс індекси. Залежно від обладнання, яке ви маєте, це не так багато, але це може бути. І це доповнює, якщо у вас є більше можливостей для вдосконалення, як це.

Крім того, я не бачу обмежень у вашій схемі, яка б гарантувала, що interaction_idвона насправді в потрібному форматі. Використання правильного типу також дасть вам це.

Якщо вам це подобається, однак, ніж використовувати bigint дозволить заощадити ще більше і мати ще кращу продуктивність. Це малоймовірно, що ваша програма настільки велика, що bigintстовпець для ідентифікатора не працюватиме.


У мене розподілена система: кілька джерел даних генерують ідентифікатори для взаємодій, тому я не можу використовувати звичайний BIGINT, якщо я не зарезервував N біт для ідентифікатора вузла.
Франсуа Бозолей

3
@ FrançoisBeausoleil, резервування N біт для ідентифікатора вузла дорівнює використанню кожного N-го числа в послідовності (і тому його легко здійснити). Також ви можете скористатися складовими ключами.
Нерозумно

1
Координація декількох послідовностей (з ідентифікатором вузла) є адміністративною проблемою на практиці та схильною до людських помилок. Я не бачу причин не використовувати UUID в цьому сценарії, тим більше, що біти нині дешеві (як пам'ять, так і сховище). Дійсно, саме цей сценарій є причиною, що UUID були винайдені десятиліттями тому: для обміну даними між розподіленими системами без централізованої координації .
Василь Бурк

6

Я не особа, що займається постгресією, на будь-якій ділянці уяви, але виходячи з того, що я знаю про SQL Server, чим більше рядків ви зможете помістити на сторінку даних, тим краще будете мати більшу ефективність (читання даних з диска зазвичай найдорожча операція). Таким чином, перехід від 36 іш 1 байт широкого поля до 16 байтового GUID видається прямим економією витрат. Чим менше читань ви можете виконати, тим швидше ви зможете повернути результати. Все це, звичайно, передбачає, що GUID / UUID задовольняє бізнес-потреби таблиці. Якщо UUID його задовольняє, чи би bigint ? Це ще більше погодить ваше сховище коштує ще 8 байт на рядок.

Редагуйте 1

Для символьних даних у Postgres для них є додаткова вартість зберігання. Короткі рядки під 127 байтами мають накладні витрати на 1 байт, тоді як все, що довше, має 4 байти. Це означає, що другий респондент придумав вартість 40 байт для 36-байтного поля. Але є також варіант стиснення рядків, тому, можливо, це не буде коштувати повних 40. Я не можу сказати, якою була б кінцева вартість, але основи залишаються: все, що перевищує 16 байт, збільшить вартість зберігання, прочитати потрібно довше і споживають більше пам’яті.

Вимога зберігання для короткого рядка (до 126 байт) становить 1 байт плюс фактичний рядок, який включає пробіл у випадку символів. Більш довгі рядки мають 4 байти накладних витрат замість 1. Довгі рядки стискаються системою автоматично, тому фізична потреба на диску може бути меншою.


3

Окрім проблеми з простором, пам’ятайте, що вам потрібно буде змінити кожну таблицю, щоб використовувати правильний тип даних, або ваша продуктивність приєднання буде поганою.


Це було дано, але дякую, що нагадали.
Франсуа Бозолей

3
Роблячи такі великі зміни, я виявляю, що записування всього (незалежно від того, наскільки просто ця річ запам'ятовується) зазвичай окупається.
mrdenny

3

На додаток до економії розміру даних та індексів (як говорять інші), що не означає економію вводу / виводу, те, що вам потрібно врахувати, полягає в тому, як ви будете генерувати нові значення interaction_idта як впливатиме на індекси та умови запиту (приєднується).

Що стосується індексу - він буде меншим, однак, якщо багато ваших запитів використовують сканування індексів для переходу на UUID, це може зробити неможливе сканування індексів (залежно від способу генерації UUID) та bigint може бути набагато кращим вибором.

Нарешті, оскільки фактичний вплив на ефективність залежить також від моделей використання та розподілу даних, ви повинні запустити тести та створити середовище розробки та тестування, в якій ви можете перевірити свої зміни.

Це дасть вам набагато точнішу відповідь про вплив на продуктивність.


Дякуємо за корисний внесок і ласкаво просимо на сайт :)
Джек каже, спробуйте topanswers.xyz

Мої схеми доступу проходять через діапазони дат, ПРИЄДНУЙСЯ за допомогою ім'я екрана або через UUID. Не передбачається сканування діапазону на унікальний ідентифікатор. Дякую за вашу відповідь, дуже інформативно.
Франсуа Бозолей
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.