Буде пошук пошуку в індексах помітно швидшим за допомогою char vs varchar, коли всі значення становлять 36 знаків


30

У мене є застаріла схема (відмова від відповідальності!), Яка використовує створений на основі хешу ідентифікатор для основного ключа для всіх таблиць (їх багато). Приклад такого ідентифікатора:

922475bb-ad93-43ee-9487-d2671b886479

Неможливо сподіватися на зміну цього підходу, проте продуктивність із доступом до індексу є низькою. Якщо відмінити безліч причин, це може бути одне, що я помітив, що здавалося менш оптимальним - незважаючи на те, що всі значення id у всіх багатьох таблицях мають рівно 36 символів, тип стовпця є varchar(36), ні char(36) .

Чи може зміна типів стовпців на фіксовану довжину char(36)принести якісь значні переваги від показника, окрім дуже малого збільшення кількості записів на індексній сторінці тощо?

Тобто чи виконують постграми набагато швидше, коли мають справу з типами фіксованої довжини, ніж із типами змінної довжини?

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

Відповіді:


40

Ні . Немає отримати взагалі . У посібнику прямо вказано :

Порада: між цими трьома типами немає різниці в продуктивності , окрім збільшення місця для зберігання даних при використанні пустого типу та декількох додаткових циклів процесора для перевірки довжини під час зберігання у стовпчику, обмеженому довжиною. Хоча character(n)має переваги в роботі в інших системах баз даних, у PostgreSQL такої переваги немає; насправді, character(n)як правило, найповільніша з цих трьох через додаткові витрати на зберігання. У більшості ситуацій text або їх character varyingслід використовувати замість цього .

Сміливий акцент мій.

char(n)це значною мірою застарілий, марний тип. Дотримуйтесь varchar(n). Якщо вам не потрібно виконувати довжину,varchar або це textбуло б трохи швидше. Ви не зможете виміряти різницю.

Крім того, якщо всі рядки мають довжину рівно 36 символів, жоден спосіб зберігання пам’яті не є, навіть мізерним. Обидва мають однаковий розмір на диску і в оперативній пам'яті. Ви можете спробуватиpg_column_size() (на виразі та на стовпці таблиці).

Пов'язані:

Ви не просили інших варіантів , але я згадаю два:

  1. COLLATION- якщо ви не запускаєте свою БД із порівнянням "C" . Колекція часто не помічається і, можливо, дорога. Оскільки ваші рядки не здаються значущими природною мовою, дотримуватися COLLATIONправил, мабуть, немає сенсу . Пов'язані:

    Широкий показник порівняння (серед іншого) впливу COLLATE "C"на ефективність:

  2. UUID , очевидно. Ваш рядок підозріло виглядає як UUID (32 шістнадцяткових цифр плюс 4 роздільники). Було б набагато ефективніше зберігати їх як фактичнийuuidтип даних, який є швидшим у декілька способів і займає лише 16 байт - на відміну від 37 байт в оперативній пам’ятіchar(36)або дляvarchar(36)(абозберігається без роздільників, лише 32 визначальних символи), або 33 байтів на диску. Але вирівнювання вирівнювання в багатьох випадкахпризведе до 40 байт.) ТакожCOLLATIONне має значення дляuuidтипу даних.

    SELECT '922475bb-ad93-43ee-9487-d2671b886479'::uuid

    Це може бути корисно (останні розділи):

    Дивись також:


чи означає це, що char / varchar (n) з обмеженою довжиною буде витрачати цикли процесора на перевірку обмеження, тоді як текстове поле змінної довжини зберігатиме текст окремо менш доступним способом порівняно з char, який виграє в цьому сценарії і це виграш навіть варто розглянути, скажімо, 10 мільйонів рядків з фрагментом тексту
PirateApp

1
@PirateApp: char(n)майже ніколи не перемагає в жодному відношенні. Не використовуйте його. Типи даних textі varchar(без модифікатора довжини) є бінарними сумісними і мають однакові характеристики продуктивності. Існують історичні причини того, що обидва співіснують у Постгресі. Внутрішньо text- це "кращий" тип серед типів рядків (який може впливати на дозвіл типу функції). Цикли процесора для примусового виконання varchar(n)ледь не мають значення. Використовуйте обмеження довжини, коли це потрібно . В даному випадку uuidє реальним переможцем.
Ервін Брандстеттер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.