Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Оптимизация структуры таблиц MySQL и влияние размера строки

Автор вопроса: NilsОтветов: 2

Одна из таблиц моей базы данных стала довольно большой, и я думаю, что это влияет на производительность моего сайта (это определенно делает резервное копирование намного медленнее).

Он имеет ~ 13 000 000 строк и имеет размер 4,2 ГБ, из которых 1,2 ГБ - это данные.

Структура выглядит следующим образом:

CREATE TABLE IF NOT EXISTS `t1` (
  `id` int(10) unsigned NOT NULL,
  `int2` int(10) unsigned NOT NULL,
  `int3` int(10) unsigned NOT NULL,
  `int4` int(10) unsigned NOT NULL,
  `char1` varchar(255) NOT NULL,
  `int5` int(10) NOT NULL,
  `char2` varchar(1024) DEFAULT NULL,
  `char3` varchar(1024) NOT NULL,
  PRIMARY KEY (`id`,`int2`,`int3`,`int4`),
  KEY `key1` (`id`,`int2`,`char1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

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

Я думал о нескольких способах оптимизации этого, и мне было интересно, какой из них будет тем, который следует преследовать:

  1. char1 (который находится в индексе) на самом деле содержит только около 40 000 различных строк. Я мог бы переместить строки во вторую таблицу (idchar -> char), а затем просто сохранить идентификатор в моей основной таблице за счет дополнительного шага поиска идентификатора во время вставки и выбора.
  2. char2 и char3 часто пусты. Я мог бы переместить их в отдельную таблицу, а затем выполнить LEFT JOIN при выборе.
  3. Даже если char2 и char3 содержат данные, они обычно короче 1024 символов. Я мог бы, вероятно, сократить их до ~ 200.

Какой из них вы считаете наиболее перспективным? Действительно ли уменьшение размера строки (либо путем преобразования char1 в целое число, либо путем удаления/изменения размера столбцов) в таблицах MySQL InnoDB оказывает большое влияние на производительность?

Спасибо

  • Рассматривали ли вы возможность разметить свою таблицу? Что касается медленного резервного копирования, рассматривали ли вы возможность использования двоичного журнала для инкрементного резервного копирования или использования подчиненного устройства репликации в качестве сервера резервного копирования (как описано в разделе Методы резервного копирования базы данных)? eggyal 16.03.2014
  • Я не рассматривал разделение, нет. Как вы думаете, это поможет в моем случае? Читая страницу справки, я действительно не понимаю, какое практическое применение могло бы быть для моей проблемы. Nils 16.03.2014
  • Это действительно зависит от того, с какими практическими проблемами вы сталкиваетесь. Вы упоминаете только медленные резервные копии: если у вас нет других проблем с производительностью, то я не думаю, что разбиение на разделы дает вам какие-либо преимущества. eggyal 16.03.2014

sqlinnodb

Ответы

Ответ 1 · рейтинг 2 · Gordon Linoff

Есть несколько вариантов. Судя по тому, что вы говорите, перемещение char1 на другой стол кажется вполне разумным. Дополнительный поиск может при некоторых обстоятельствах быть даже быстрее, чем сохранение необработанных данных в таблицах. (Это происходит, когда повторяющиеся значения приводят к тому, что таблица становится больше, чем необходимо, особенно когда большая таблица может быть больше, чем доступная память.) И это сэкономит место как в таблице данных, так и в соответствующем индексе.

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

Перемещение char3 и char4 в другую таблицу окажет минимальное влияние. Накладные расходы на ссылку на другую таблицу съели бы любой выигрыш в пространстве. Вы можете сэкономить пару байтов на запись, сохранив их как varchar(255), а не varchar(1024).

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

Ответ 2 · рейтинг 1 · ericpap

Есть несколько факторов, которые могут повлиять на производительность вашей БД. Разбиение на разделы, безусловно, лучший вариант, но не всегда можно сделать. Если вы ищете char1 перед вставкой, то разделение может быть проблемой, потому что вам нужно искать ключ во всех частях. Вы должны проанализировать, как генерируются данные и, что наиболее важно, как вы делаете запросы для этой таблицы. Это ключ, поэтому вы должны публиковать свои запросы в этой таблице. В случае с char2 и char3 переход на другую таблицу не будет иметь никакого значения. Вы также должны упомянуть о физическом распределении ваших данных. Вы используете один файл данных? Находятся ли файлы данных на том же физическом диске, что и SO? Дайте больше деталей, чтобы мы могли оказать вам больше помощи.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы