Подобный вопрос был задан ранее
Влияние на производительность размеров MySQL VARCHAR
Вот выдержка из моего ответа
Вы должны понять компромиссы использования CHAR против VARCHAR
С полями CHAR вы выделяете именно то, что получаете. Например, CHAR (15) выделяет и хранит 15 байтов, независимо от того, какие символы вы размещаете в поле. Работа со строками проста и понятна, поскольку размер поля данных полностью предсказуем.
С полями VARCHAR вы получите совершенно другую историю. Например, VARCHAR (15) фактически выделяет динамически до 16 байтов, до 15 для данных и, по крайней мере, 1 дополнительный байт для хранения длины данных. Если у вас есть строка 'hello' для хранения, которая будет занимать 6 байтов, а не 5. Во всех случаях при обработке строк всегда должна выполняться проверка длины.
Компромисс становится более очевидным, когда вы делаете две вещи: 1. Хранение миллионов или миллиардов строк. 2. Индексирование столбцов, которые являются CHAR или VARCHAR.
TRADEOFF # 1 Очевидно, что VARCHAR обладает преимуществом, поскольку данные переменной длины будут создавать меньшие строки и, следовательно, меньшие физические файлы.
TRADEOFF # 2 Поскольку поля CHAR требуют меньших манипуляций со строками из-за фиксированной ширины поля, поиск индекса по полю CHAR в среднем на 20% быстрее, чем поиск полей VARCHAR. Это не какая-то догадка с моей стороны. Книга MySQL Database Design and Tuning провела нечто удивительное на столе MyISAM, чтобы доказать это. Пример в книге сделал что-то вроде следующего:
ALTER TABLE tblname ROW_FORMAT=FIXED;
Эта директива заставляет все VARCHAR вести себя как CHAR. Я сделал это на своей предыдущей работе в 2007 году, взял таблицу на 300 ГБ и ускорил поиск индекса на 20%, не меняя ничего другого. Он работал как опубликовано. Тем не менее, он дал таблицу почти в два раза больше, но это просто возвращает к компромиссу № 1.
Вы можете проанализировать хранимые данные, чтобы увидеть, что MySQL рекомендует для определения столбцов. Просто запустите следующее для любой таблицы:
SELECT * FROM tblname PROCEDURE ANALYSE();
Это будет проходить по всей таблице и рекомендовать определения столбцов для каждого столбца на основе содержащихся в нем данных, минимальных значений полей, максимальных значений полей и т. Д. Иногда вам просто нужно руководствоваться здравым смыслом при планировании CHAR против VARCHAR. Вот хороший пример:
Если вы храните IP-адреса, маска для такого столбца должна содержать не более 15 символов (xxx.xxx.xxx.xxx). Я бы сразу CHAR(15)
понял, потому что длины IP-адресов не будут сильно меняться, а сложность манипулирования строками будет контролироваться дополнительным байтом. Вы все еще можете сделать PROCEDURE ANALYSE()
против такой колонны. Может даже порекомендовать VARCHAR. В этом случае мои деньги все еще будут на CHAR, а не на VARCHAR.
Проблемы CHAR и VARCHAR могут быть решены только путем правильного планирования. С большой силой приходит большая ответственность (клише, но это правда).
ОБНОВИТЬ
Когда дело доходит до MD5, strlen
внутреннее вычисление должно быть исключено при переключении всего формата строки. Там не будет необходимости изменять определение поля.
Если ключ MD5 - единственный присутствующий VARCHAR, я бы пошел на него и преобразовал формат строки таблицы в фиксированный . Если имеется большое количество других полей VARCHAR, они также выиграют. В обмен на это таблица расширилась бы примерно вдвое. Но запросы должны ускоряться примерно на 20% больше без дополнительной настройки.