Какой размер я сохраню, если изменить столбец INT на MEDIUMINT? - PullRequest
0 голосов
/ 27 апреля 2018

Я учусь оптимизировать свою базу данных, повторно выбирая правильные типы данных для столбцов, и я хочу знать, какой размер я сохраню, если выберу MEDIUMINT (3 байта) вместо INT (4 Байт)

AFAIK - и поправьте меня, если я ошибаюсь - мне нужно, чтобы размер базы данных был как можно меньшим, чтобы поместиться в ОЗУ, чтобы уменьшить количество запросов жесткого диска. Размер базы данных состоит из таблиц размеров + индексов размеров

с учетом того, что у меня есть столбец INT с 10 000 000 строк и индексом B-Tree, какой размер В мегабайтах я сэкономлю, если изменил тип данных столбца с INT на MEDIUMINT при

  • размер таблицы данных?
  • размер индекса?

примечание: я знаю, что MySQL не уменьшит фактический размер на диске, если я OPTIMIZE TABLE

РЕДАКТИРОВАТЬ: Моя ситуация такова, что я скоро закончу свою первую серьезную систему в моей жизни - это система ERP, которую я планирую продавать на рынке арабского региона -. Предполагается, что базы данных с планами 1, 2, 3, 4 составляют около 2 ГБ, 4 ГБ, 10 ГБ и 40 ГБ соответственно, поэтому, если бы я мог уменьшить размер каждой базы данных без ущерба для производительности / возможностей, почему бы и нет? Если бы я мог заставить машину с 32 ГБ ОЗУ обслуживать 4 клиента вместо 2, почему бы и нет?

Ответы [ 3 ]

0 голосов
/ 27 апреля 2018

Точный размер вашего индекса будет зависеть от того, сколько у вас строк, а также от того, как выглядят данные в вашем индексе.

Если вы урезаете 1 байт на запись в ваших данных, и у вас есть 10 000 000 записей, это сэкономит вам до 10 МБ на диске для данных таблицы. Добавление индекса добавит еще немного, и у B-деревьев будет пустое пространство, но от реальных данных зависит, насколько они неэффективны.

Если вы хотите сэкономить место, убедитесь, что поле не обнуляется, потому что даже если вы заполняете все строки данными, в каждой записи есть информация, указывающая, содержит ли поле, допускающее обнуляемость, данные.

0 голосов
/ 07 мая 2018

(я не согласен с некоторыми других ответов / комментариев. Я постараюсь ответить на все вопросы, а также ответить на все вопросы, с которыми я не согласен.)

MEDIUMINT - 3 байта, экономя 1 байт на строку более INT.
TINYINT равен 1 байту, экономя 3 байта на строку более INT.
В обоих случаях в каждом INDEX, кроме PRIMARY KEY.

, сохраняется 1 или 3 байта для каждого вхождения.

Если у вас в ОЗУ больше данных + индекса, чем места в ОЗУ, то целесообразно разумно уменьшить типы данных , но быть консервативным.

Используйте MEDIUMINT UNSIGNED (и т. Д.), Если значение неотрицательно, например, для AUTO_INCREMENT. Это дает вам предел 16M вместо 8M. (Да, да, это небольшое улучшение.)

Остерегайтесь "прожига" AUTO_INCREMENT id - INSERT IGNORE (и несколько других команд) выделят следующий auto_inc перед проверкой, будет ли он использоваться.

Даже если data + index превышает размер RAM (на самом деле innodb_buffer_pool_size), он может не замедляться до скорости диска - это зависит от схем доступа к данным. Остерегайтесь UUID, они ужасно случайны. Использование UUID, когда вы не можете кэшировать весь индекс, смертельно. Буфер_пул - это кеш . (Я видел, что набор данных объемом 1 ТБ работал достаточно быстро, только с 32 ГБ ОЗУ и вращающимся диском.)

Использование ALTER TABLE для изменения типа данных возможно (я не уверен) перестраивает таблицу, выполняя, таким образом, эквивалент OPTIMIZE TABLE.

Если таблица была создана с помощью innodb_file_per_table = OFF и вы поворачиваете ее ON перед выполнением ALTER, вы получите отдельный файл для таблицы, , но ibdata1 не будет уменьшаться (вместо этого у него будет намного больше свободного места).

Выравнивание 3-байтовых чисел - не проблема . Полномочия 2 здесь не актуальны. MySQL предполагает, что все столбцы имеют плохие границы и плохие размеры. Все числа преобразуются в общий формат (64-разрядные числа) для дальнейшей работы. Это преобразование составляет незначительную часть общего времени - выборка строки (даже если она кэширована) является самой дорогой частью.

При ограничении ввода / вывода сжатие типов данных приводит к увеличению числа строк в блоке, что приводит к меньшему количеству обращений к диску (за исключением случая UUID). При ограничении ввода / вывода попадание на диск приводит к огромным потерям производительности.

"NULLS не занимать пробел" - https://dev.mysql.com/doc/internals/en/innodb-field-contents.html. Итак, опять же, меньше ввода / вывода. Но будьте осторожны, если это приведет к дополнительной проверке NULL в SELECT, это может привести к сканированию таблицы вместо использования индекса. Удар по 10М рядам намного хуже, чем по нескольким.

Что касается того, сколько клиентов вы можете уместить в 32 ГБ - может быть, 6 или больше. Помните, буфер_пул является кешем; данные и индексы кэшируются по блокам. (Блок InnoDB составляет 16 КБ.)

Еще одна вещь ... Намного проще сократить типы данных до того, как поступит в производство. Итак, делай то, что можешь сейчас, смело.

0 голосов
/ 27 апреля 2018

Просто используйте INT, если у вас нет конкретной, измеримой проблемы. Вы только запутаетесь, если будете беспокоиться о каждом байте в эпоху, когда даже у самых экономных смартфонов их миллиард на память.

Мне нужно, чтобы размер базы данных был как можно меньше, чтобы поместиться в ОЗУ, чтобы уменьшить количество запросов жесткого диска.

Нет, нет. Вам нужна база данных, чтобы с ней было легко работать и адекватно выполнять . В эпоху баз данных на основе SSD ввод / вывод не будет проблемой до тех пор, пока вы не начнете работать в больших масштабах, а когда и когда наступит этот день, вы сможете провести измерения и понять конкретные проблемы, с которыми вы столкнулись.

Удаление одного байта из поля INT вряд ли улучшит ситуацию, поскольку трехбайтовые целочисленные значения - это не то, с чем ваш ЦП может напрямую иметь дело. Они будут преобразованы в четыре байта и выровнены должным образом, чтобы их можно было понять, что является сложным процессом по сравнению с чтением простого старого 32-разрядного целого числа.

Помните, MySQL пришла из эпохи, когда высокопроизводительный сервер имел 64 мегабайт памяти и жесткий диск 9 гигабайт считался огромным. Тогда вам приходилось сбривать байты, потому что их было всего несколько.

Теперь у нас есть другие проблемы, например, вы случайно исчерпали свое 24-битное целочисленное пространство, как Slashdot сделал , когда их сайт вышел из строя именно из-за того типа «оптимизации», который вы намереваетесь сделать здесь .

Будь осторожен. Оптимизируйте, когда у вас есть конкретная причина, а не только потому, что вам это нужно. Избегать преждевременной оптимизации - это постоянная борьба в разработке, но если вы дисциплинированы, вы можете избежать этого.

...