Подібне питання задавали і раніше
Наслідки для продуктивності розмірів MySQL VARCHAR
Ось уривок моєї відповіді
Ви повинні усвідомити компроміси використання CHAR проти VARCHAR
З полями CHAR те, що ви виділяєте, саме те, що ви отримуєте. Наприклад, CHAR (15) виділяє і зберігає 15 байт, незалежно від того, як символи ви розміщуєте в полі. Маніпулювання рядками просте і просте, оскільки розмір поля даних повністю передбачуваний.
З полями VARCHAR ви отримуєте зовсім іншу історію. Наприклад, VARCHAR (15) насправді динамічно виділяє до 16 байт, до 15 для даних і, щонайменше, 1 додатковий байт для збереження довжини даних. Якщо у вас є рядок "привіт", який займе 6 байтів, а не 5. Маніпуляція з рядками завжди повинна виконувати певну форму перевірки довжини у всіх випадках.
Компроміс є більш очевидним, коли ви виконуєте дві речі: 1. Зберігання мільйонів чи мільярдів рядків 2. Індексація стовпців, що є або CHAR або VARCHAR
TRADEOFF №1 Очевидно, VARCHAR має перевагу, оскільки дані змінної довжини створюватимуть менші рядки і, таким чином, менші фізичні файли.
TRADEOFF # 2 Оскільки поля CHAR потребують меншої маніпуляції з рядками через фіксовану ширину поля, пошук індексів щодо поля CHAR в середньому на 20% швидший, ніж для полів VARCHAR. Це не будь-яка здогадка з мого боку. Книга Дизайн та настройка баз даних MySQL виконала щось чудове на таблиці MyISAM, щоб довести це. Приклад у книзі зробив щось подібне:
ALTER TABLE tblname ROW_FORMAT=FIXED;
Ця директива змушує всіх VARCHAR поводитися як CHAR. Я робив це на своїй попередній роботі ще в 2007 році, і взяв таблицю на 300 ГБ і збільшив пошукові показники на 20%, не змінюючи нічого іншого. Це працювало як опубліковано. Однак вона створила таблицю майже вдвічі більше, але це просто повертається до компромісу №1.
Ви можете проаналізувати дані, що зберігаються, щоб побачити, що рекомендує MySQL для визначення стовпців. Просто запустіть наступне проти будь-якої таблиці:
SELECT * FROM tblname PROCEDURE ANALYSE();
Це дозволить пройти всю таблицю та рекомендувати визначення стовпців для кожного стовпця на основі даних, які він містить, мінімальних значень поля, максимальних значень поля тощо. Іноді просто потрібно використовувати здоровий глузд при плануванні CHAR vs VARCHAR. Ось хороший приклад:
Якщо ви зберігаєте IP-адреси, маска для такого стовпця має максимум 15 символів (xxx.xxx.xxx.xxx). Я б стрибнув прямо CHAR(15)
в серцебиття, тому що довжина IP-адрес не буде значною мірою змінюватись, а додаткова складність маніпуляцій з рядками контролюється додатковим байтом. Ви все ще можете PROCEDURE ANALYSE()
проти такої колонки. Може навіть рекомендувати VARCHAR. У цьому випадку мої гроші все одно будуть знаходитися на CHAR за VARCHAR.
Проблеми CHAR проти VARCHAR можна вирішити лише за допомогою належного планування. З великою силою приходить велика відповідальність (кліше, але правда).
ОНОВЛЕННЯ
Що стосується MD5, то обчислення strlen
внутрішньо слід виключити при переключенні всього формату рядків. Не потрібно було б змінювати визначення поля.
Якщо ключ MD5 є єдиним присутнім VARCHAR, я б пішов на нього і перетворив формат рядка таблиці у фіксований . Якщо є значна кількість інших полів VARCHAR, вони також отримають користь. В обмін на це таблиця розшириться приблизно вдвічі більше її розміру. Але запити повинні прискорюватися приблизно на 20% більше без додаткової настройки.