`id` bigint(20) unsigned NOT NULL auto_increment,
Тебе действительно нужен BIGINT? Вы, вероятно, можете сойти с INT. Если бы вы вставляли 1000 строк в секунду 24 часа в сутки, вам потребовалось бы 136 лет, чтобы исчерпать все значения в 32-разрядном целом числе без знака.
Это изменение уменьшит размер таблицы на 152,5 МБ для 40 миллионов строк и уменьшит размер индекса первичного ключа на 158,8 МБ для 40 миллионов строк.
`some_other_id_not_fk` int(10) unsigned default NOT NULL,
Вы заявляете, что это имеет только 7 различных значений. Это должен быть тип INT тогда? Не могли бы вы использовать вместо TINYINT? Это резко уменьшит размер индекса.
Это уменьшит размер вашей таблицы на 114,4 МБ для 40 миллионов строк и уменьшит размер индекса some_other_id_not_fk
примерно на столько же.
`event_time` datetime NOT NULL,
Вам нужен DATETIME? DATETIME занимает 8 байтов, TIMESTAMP занимает 4 байта. Если вы можете использовать TIMESTAMP, это значительно сократит размер данных и индекса. Помните об ограничениях полей TIMESTAMP, таких как Y2K38 , и о том, как они ведут себя относительно часовых поясов и репликации.
Это изменение уменьшит размер таблицы на 152,5 МБ для 40 миллионов строк и уменьшит размер индекса первичного ключа на 158,8 МБ для 40 миллионов строк.
Эти три изменения значительно уменьшат размер ваших данных, а также индексов.
Общая экономия пространства
- Таблица: 152,5 + 152,5 + 114,4 = 419,4 МБ
- Индекс: 158,8 + 158,8 + ~ 115 = 432,6 МБ
Всего : 852 МБ
Как и другие предлагали, вам могут даже не понадобиться все заданные вами индексы. При такой низкой селективности на some_other_id_not_fk
велика вероятность того, что оптимизатор запросов даже не будет использовать этот индекс и вместо этого выберет полное сканирование таблицы. Полное удаление этого индекса приведет к значительной экономии места для ваших индексов.
Если бы вы могли предоставить несколько примеров запросов, я могу помочь вам в дальнейшем.
Кроме того, вы вставляете в эту таблицу под большой нагрузкой чтения? Имейте в виду, что SELECTs в MyISAM заблокирует INSERT.
Обновление
Большинство людей предлагают переместить ваше поле some_other_id_not_fk
в индекс event_time
, чтобы новый индекс был на (event_time, some_other_id_not_fk)
. Я буду рекомендовать то же самое, но с важным предостережением.
Этот индекс будет полезен для запросов, для которых вы фильтруете только по event_time
, или если вы фильтруете по event_time
и some_other_id_not_fk
. не будет использоваться для фильтрации запросов только на some_other_id_not_fk
- произойдет полное сканирование таблицы.
Более того, если ваши запросы всегда фильтруются по и event_time
и some_other_id_not_fk
, тогда не используют порядок индекса (event_time, some_other_id_not_fk)
. Вместо этого вам следует использовать индекс (some_other_id_not_fk, event_time)
.
Наличие поля с наименее селективным (большинство дубликатов) первым позволит значительно увеличить сжатие для вашего индекса и, таким образом, значительно уменьшить занимаемую область на диске.