Какое влияние оказывает TOAST на производительность? (добавив сто столбцов varchar) - PullRequest
0 голосов
/ 22 февраля 2020

Рассмотрим таблицу со следующими данными:

  • id bigint Автоинкремент
  • name символ меняется (255) NULL
  • category символ меняется (255) NULL
  • english символ меняется (255) NULL
  • french символ меняется (255) NULL
  • pivot символ меняется (255) NULL
  • credits символ варьируется (255) NULL
  • hash символ варьируется (20) NULL

Столбец english содержит данные следующих размер (в байтах): максимум 116, минимум 5, среднее значение 42, медиана: 40.
Количество строк в таблице составляет около 30 000 и вряд ли изменится.
Новые 107 столбцов будут переводами английского языка. sh.

Повлияет ли добавление 107 столбцов на производительность?

Сайт Postgres сообщает, что максимальное количество столбцов в таблице Postgres равно

250-1600 в зависимости от типов столбцов

и

Максимальное количество столбцов для таблицы дополнительно уменьшается, так как сохраняемый кортеж должен помещаться в один 8192 -байтовая страница кучи

Подпадают ли данные под этот предел?

Размер наибольшей строки

Каков фактический размер хранилища строк таблицы? pg_column_size - это

Количество байтов, используемых для хранения определенного значения (возможно сжатого)

SELECT id, pg_column_size(t.*) FROM table as t ORDER BY pg_column_size DESC

-- Some stats derived from the query:
-- Min 87 bytes
-- Max 514 bytes
-- Average 216 bytes
-- Median: 209 bytes

Но здесь никакого сжатия не происходит , потому что :

Когда строка, которая должна быть сохранена, «слишком широка» (порог для этого составляет 2 КБ по умолчанию), механизм TOAST сначала пытается сжать любой широкие значения поля. Если этого недостаточно, чтобы получить строку размером менее 2 КБ, она разбивает значения широких полей на куски, которые сохраняются в связанной таблице TOAST. Каждое исходное значение поля заменяется небольшим указателем, который показывает, где можно найти эти данные «вне линии» в таблице TOAST. Таким образом, TOAST попытается сжать строку таблицы пользователя до 2 КБ, но до тех пор, пока она может опуститься ниже 8 КБ, этого достаточно, и строка может быть успешно сохранена.

Сжатие начнёт увеличиваться, как только таблица станет больше и будут добавлены эти новые столбцы.

Мне неясно Какой будет степень сжатия для таких данных?

Интересно, насколько эффективно это будет для множества коротких многоязычных предложений. Кроме того, попытался найти точное имя алгоритма сжатия , используемого Postgres: в документах указано "семейство методов сжатия LZ", но какой из них - LZ77? LZ78? Поворот к одному из них?

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

TOAST'ed?

Если размер таблицы выходит за пределы страницы если ограничить размер, то Posgres будет полагаться на TOAST не только для сжатия, но и для разделения данных для строк вне строки.

Я понимаю, что это увеличит время выборки для тех строк, которые не соответствуют … Но Какое влияние оказывает TOAST на производительность? Это ничтожно мало для такого варианта использования?

Итог

В конце дня…

  • Добавляет эти 107 столбцы хорошая идея, или я должен использовать другой подход?
  • Если все в порядке, насколько важно извлекать только те столбцы, которые нужны пользователю? (Ни один пользователь не будет нуждаться во всех из них.)

Или я подхожу к этому неправильным путем, то есть это случай преждевременной оптимизации, где мне было бы лучше просто добавить столбцы и только расследовать позже, если столкнулись с проблемами?


Использование Postgres 9.6. Обновление является опцией, если это необходимо.

Ответы [ 2 ]

0 голосов
/ 23 февраля 2020

Я не знаю, подпадает ли это под «преждевременную оптимизацию», а не под плохой дизайн. Так или иначе, вам понадобится какой-то метод узнать, какая из 108 версий вам нужна. Но что происходит, когда вам нужно добавить 108-й перевод или удалить, скажем, 93-й. Поэтому используйте эту информацию, чтобы сформировать ключ к таблице перевода. Что-то вроде Translation_Test (for_ref_in bigint, текст на языке, текст перевода). Затем получите доступ к необходимому тексту (включая, возможно, версию Engli sh) из этой таблицы.

0 голосов
/ 22 февраля 2020

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

Я бы просто скопировал версию Engli sh в каждый из 107 столбцов. , Это должно быть достаточно, чтобы получить некоторые полезные результаты. Вы могли бы волноваться, что повторение заставило бы сжатие быть своеобразным; но каждое значение сжимается изолированно, поэтому «не знает», что оно идентично некоторому другому значению.

Мне неясно, какой будет степень сжатия для таких данных?

Не очень. Например, ваш абзац, который я цитировал первым, не дает никакой выгоды от сжатия (когда я скопировал его в 107 других столбцов). Короткие сегменты обычного текста не имеют достаточного количества повторений, чтобы быть очень сжимаемыми. Перевод их на другие языки вряд ли изменит это.

Если все в порядке, насколько важно извлекать только те столбцы, которые нужны пользователю? (Ни одному пользователю не понадобятся все из них.)

На этот вопрос очень четкий ответ. Вы должны абсолютно выбрать только то, что вам нужно. Сбор строки из 100+ поджаренных столбцов, просто чтобы отбросить большинство из них, замедлит вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...