Я розробляю додаток в Ruby on Rails за допомогою бази даних PostgreSQL (9.4). У моєму випадку використання стовпці в таблицях будуть шукатися дуже часто, оскільки вся точка програми шукає дуже конкретні атрибути на моделі.
Наразі я вирішую, чи використовувати integer
тип або просто використовувати типовий тип рядка (наприклад character varying(255)
, типовим для Rails ) для стовпців, тому що я не впевнений, яка різниця в продуктивності буде в індексі.
Ці стовпці є перерахунками . Вони мають фіксований розмір для кількості можливих значень, які вони можуть мати. Більшість довжин перерахунків не перевищують 5, тобто індекс буде більш-менш фіксованим протягом усього життя програми ; таким чином, цілі та рядкові індекси були б однаковими за кількістю вузлів.
Однак рядок, який буде індексовано, може мати довжину близько 20 символів, що в пам'яті приблизно в 5 разів перевищує ціле число (якщо ціле число - 4 байти, а рядки є чистими ASCII в 1 байті на символ, то це справедливо). Я не знаю, як двигуни бази даних роблять пошук індексів, але якщо йому потрібно "сканувати" рядок, поки вона точно не збігається , то, по суті, це означає, що пошук рядків був би в 5 разів повільніше, ніж цілочисельний пошук; "сканування", поки збіг для цілого пошуку буде 4 байти замість 20. Це те, що я собі уявляю:
Значення пошуку становить (ціле число) 4:
сканування ............................ ЗНАЙДЕНО | отримання записів ... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
Значенням пошуку є (рядок) "some_val" (8 байт):
сканування ................................................. .................................... ЗНАЙДЕНО | отримання записів ... | BYTE_1 | BYTE_2 | BYTE_3 | BYTE_4 | BYTE_5 | BYTE_6 | BYTE_7 | BYTE_8 | ... |
Я сподіваюся, що це має сенс. В основному, оскільки ціле число займає менше місця, його можна "узгодити" швидше, ніж його рядковий рядок. Можливо, це абсолютно неправильна здогадка, але я не експерт, тому я прошу вас, хлопці! Я припускаю, що ця відповідь, яку я щойно знайшов, здається, підтримує мою гіпотезу, але я хочу бути впевненою.
Кількість можливих значень у стовпці не змінилася б за допомогою жодного, тому сам індекс не змінився (якщо я не додав нове значення до перерахунку). У цьому випадку, чи буде різниця в продуктивності використання integer
або varchar(255)
, чи використання цілого типу має більше сенсу?
Причина, про яку я запитую, полягає в тому, що enum
тип Rails відображає цілі числа на рядкові клавіші, але вони не мають бути стовпцями, орієнтованими на користувачів. По суті, ви не можете перевірити, чи є значення перерахунку допустимим, оскільки невірне значення призведе до того, ArgumentError
як можна буде запустити будь-які перевірки. Використання string
типу дозволило б перевірити валідацію, але якщо є вартість продуктивності, я краще просто зламати проблему з валідацією.
varchar(255)
наприклад, наприкладvarchar(260)
. Можливо, таке траплялося і з SQL Server 6.x, але це давно не відповідає дійсності.