Рекомендации по оптимальному использованию типов данных в MySQL |
[исправить] |
Материал основан на рекомендациях, данных в книге "MySQL Оптимизация
производительности", в которой подробно рассказано почему каждая рекомендация
работает так, а не иначе. В заметке лишь приведены ключевые моменты, в стиле
"Делайте так!". Все нижесказанное будет относиться к MySQL 5.1 и выше. Движок
InnoDB. Для MyISAM также верно почти все нижесказанное.
Прежде чем говорить о типах, рекомендация относительно NULL/ NOT
NULL. Наличие флага NULL, увеличивает объем данных при хранении на диске.
И немного нагружает индексы. Определяйте типы полей как NOT NULL, и указывайте
DEFAULT VALUE. Большой выигрыш в производительности это не даст, но как
говорится "Копейка рубль бережет".
UUID - удалите тире или преобразуйте в 16 байтовые числа UNHEX() и
сохранить в столбце BIN(16). Извлекать данные в шестнадцатеричном формате можно
с помощью MySQL функции HEX().
IP адреса лучше всего хранить как UNSIGNED INT. И использовать MySQL
функции INET_ATON() и INET_NTOA()
Итак, наиболее часто используются типы int, varchar/char, date/time, enum.
Выбор оптимальных типов данных.
1. INT - все понятно, ничего интересного.
2. CHAR / VARCHAR
VARCHAR имеет переменную длину в файле. Занимает столько места сколько записано
данных. При UPDATE если данных стало больше - выделяется место в другом месте
файла. Это создает дополнительную нагрузку и является причиной фрагментации.
Используйте VARCHAR если данные обновляются редко, либо используется сложная
кодировка, например UTF-8. Идеально для хранения неизменяемых данных.
CHAR имеет фиксированную длину в файле. Фрагментация ему не страшна. CHAR
полезен когда нужно хранить короткие строки приблизительно одинаковой длинны.
Частое обновление не ведет к фрагментации. Идеален для хранение MD5 (CHAR(32)).
Старайтесь использовать CHAR, сортировка по такому полю обходится сильно "дешевле".
3. DATETIME / TIMESTAMP - Используйте TIMESTAMP, он занимает на диске меньше места.
4. ENUM
При создании таблицы:
CREATE TABLE enum_test ( e ENUM('fish','dog','apple') NOT NULL);
создается справочник-индекс в *.frm файле. И при последующих INSERT/UPDATE в
базу записывается номер(индекс) ENUM поля.
INSERT INTO enum_test(e) VALUES ('fish'),('dog'),('apple');
SELECT e + 0 FROM enum_test;
вернет
1
3
2
И сортировка происходит (сюрприз) по этим целочисленным значениям :)
SELECT e FROM enum_test ORDER BY e;
fish
apple
dog
Обойти это неудобство можно используя FIELD().
Не используйте JOIN между CHAR/VARCHAR и ENUM.
|
|
|
|
Раздел: Корень / Программисту и web-разработчику / SQL и базы данных / MySQL специфика / Оптимизация и администрирование MySQL |