Стоит ли тратить время на изменение типа столбца с 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
@ FrancoisBeausoleil, резервирование 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
Делая серьезные изменения, подобные этому, я обнаруживаю, что написание всего (независимо от того, насколько просто это запомнить) обычно окупается.
Мрденный

3

В дополнение к экономии в размере данных и индексов (как говорят другие), которая переводится в экономию ввода / вывода, необходимо учитывать, как вы будете генерировать новые значения interaction_idи как это повлияет на индексы и условия запроса (объединения).

Для индекса - он будет меньше, однако, если во многих ваших запросах используются сканирования индекса, переключение на UUID может сделать сканирование индекса невозможным (в зависимости от того, как вы будете генерировать UUID) и bigint может быть гораздо лучшим выбором.

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

Это даст вам гораздо более точный ответ о влиянии на производительность.


Спасибо за полезный вклад и добро пожаловать на сайт :)
говорит Джек, попробуйте topanswers.xyz

Мои шаблоны доступа - через диапазоны дат, СОЕДИНЕНИЕ с использованием имени_экранов или по UUID. Сканирование диапазона по уникальному идентификатору не ожидается. Спасибо за ваш ответ, очень информативно.
Франсуа Босолей
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.