Задать вопрос

Оптимизация Mysql. Типы данных. Правильно ли я понял?

Ребят, изучаю оптимизацию БД, извиняюсь за дилетантство..
Был бы благодарен, если бы кто-нибудь помог устаканить некоторые вопросы(много прочитал, хотелось бы все собрать в кучу и получить уверенность, что правильно все понял:(

1) Всегда необходимо указывать столбцу минимально-возможный тип данных?
пример: для id primary key, если не планируется более 65 000 записей, нужно ставить smallint(5) unsigned?
поле с id-товарами: если знаю, что товаров не более 255 будет, ставить tinyint(3) unsigned?
2) Для значений флагов в БД (1,0) оптимален tinyint(1) (он же bool)? enum не стоит(если 2 значения, он будет 2 байта жрать?)?
3) Для текстового поля (например: описание товара) оптимален text? но, что если я знаю, что текст не будет более 2 000? я могу поставить varchar (2000)? varchar же меньше байт потребляет?
4) Есть поле в БД, которое все время пустое и оно не нужно(готовый движок переделываю под себя, очень много править нужно, чтобы его удалить, пока нет времени). Какой тип данных разумнее сделать? char(0)?
5) Тип Varchar потребляет памяти исходя из длины значения в поле или то, что указывается при создании - Varchar(2000)?

Просто вчера вечером придерживался вышеуказанным правилам и наоптимизировал БД так, что по статистике хостинга, нагрузка в кол-ве времени обработки запросов возросла.. А делал вот что: было id(11) primary key -> стало smallint(5) unsigned, были varchar(3333) -> стало varchar(2000), int(1) -> tinyint(1) unsigned
Вроде все верно же?
Заранее огромное спасибо. Хочется ясности
  • Вопрос задан
  • 1790 просмотров
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 2
@ollisso
1. желательно да, иначе вы неправильно используете пространство.
Пока у вас < 1000 строк это не страшно. но если у вас миллион строк - то таблицы могут уменьшится в разы.

2. можно ещё BIT но с ним сложнее работать. можно использовать tinyint.
3. если длинный текст (более 255 символов) то лучше использовать tinytext, text, longtext и тп. Плюс varchar - можно делать индекс на него. На text сделать индекс не оптимально, насколько я помню.
4. tinyint или bit
5. varchar - столько, сколько данных + системные символы (несколько байт)
char - занимает фиксированное количество места.

посмотрите, может у вас индексы слетели каким либо образом ? Обычно именно индексы оказывают серьёзное влияние на прозводительность, а не размер полей.
Ответ написан
Комментировать
saboteur_kiev
@saboteur_kiev
software engineer
В вашем случае вы пытаетесь оптимизировать место на диске и в памяти, что совсем не тоже самое, что оптимизировать скорость запросов.

1) Столбцу необходимо указывать тот тип данных, который для него подходит, и не обязательно минимально возможный. Чтобы понять имеет ли смысл экономить место, нужно проанализировать ваши запросы - по каким именно столбцам происходит поиск - вот их оптимизировать в первую очередь. Если запросы не выполняют поиск по вашему текстовому полю, то особо нет разницы какой оно длины - строка будет найдена например по id primary кей. а прочитать 2 кб или 3 кб - разницы нет. То есть ВСЕ поля минимизировать для ускорения нет смысла, разве что для уменьшения памяти.

2) sql не адресует биты, он все равно будет выделять минимально байт для хранения флага. enum не означает 2 байта, enum может означать список флагов, это вполне может быть и 1 байт со значениям 0 и 1. или 0,1,2. Зависит от базы.

3) text - удобно, если вы не знаете точный размер. varchar хранится прямо в строке, text и blob хранит там ссылку, а сами данные хранятся отдельно. С точки зрения оптимизации памяти - текст выгоднее. С точки зрения скорости доступа к данным - varchar быстрее. Плюс по text нельзя индексировать.

4) Если поле все время пустое, и вы сделали char0, то в памяти будет выделяться новая область каждый раз, когда вы в существующую строку но с пустым полем будете добавлять что-то в это поле. А если varchar(2000), то для всех существующих записей память будет выделена сразу при запуске mysql, и обновление будет происходить быстрее чем создание новой записи.

5) varchar(2000) для всех значений. На случай если вы вдруг измените строку в таблице, и чтобы это место в памяти не "раздвигать", перемещая ВСЕ данные.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы