Обработка огромной таблицы MYSQL - PullRequest
6 голосов
/ 22 июня 2011

Надеюсь, у вас все хорошо.У нас есть огромная таблица mysql под названием «posts».Он имеет около 70000 записей и имеет размер около 10 ГБ.

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

Какие возможные решения, так что обработка этой таблицы становится проще, как во всех аспектах.

Структура таблицы следующая:

CREATE TABLE IF NOT EXISTS `posts` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `thread_id` int(11) unsigned NOT NULL,
  `content` longtext CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `first_post` mediumtext CHARACTER SET utf8 COLLATE utf8_unicode_ci,
  `publish` tinyint(1) NOT NULL,
  `deleted` tinyint(1) NOT NULL,
  `movedToWordPress` tinyint(1) NOT NULL,
  `image_src` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `video_src` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `video_image_src` varchar(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `thread_title` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
  `section_title` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
  `urlToPost` varchar(280) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `posts` int(11) DEFAULT NULL,
  `views` int(11) DEFAULT NULL,
  `forum_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `subject` varchar(150) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
  `visited` int(11) DEFAULT '0',
  `replicated` tinyint(4) DEFAULT '0',
  `createdOn` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `urlToPost` (`urlToPost`,`forum_name`),
  KEY `thread_id` (`thread_id`),
  KEY `publish` (`publish`),
  KEY `createdOn` (`createdOn`),
  KEY `movedToWordPress` (`movedToWordPress`),
  KEY `deleted` (`deleted`),
  KEY `forum_name` (`forum_name`),
  KEY `subject` (`subject`),
  FULLTEXT KEY `first_post` (`first_post`,`thread_title`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=78773 ;

Благодарю вас.

ОБНОВЛЕНО

Примечание: хотя я полон ответов, но почти все ответы касались оптимизации текущей базы данных, а нео том, как вообще обрабатывать большие таблицы.Хотя я могу оптимизировать базу данных на основе полученных ответов, она действительно не отвечает на вопрос об обработке огромных баз данных.Прямо сейчас я говорю о 70 000 записей, но в течение следующих нескольких месяцев, если не недель, мы вырастем до величины.Каждая запись может иметь размер около 300 КБ.

Ответы [ 3 ]

6 голосов
/ 22 июня 2011

Мой ответ также является дополнением к двум предыдущим комментариям.

Вы проиндексировали половину своей таблицы. Но если вы посмотрите на некоторые индексы (publish, delete, MoveToWordPress), вы заметите, что они равны 1 или 0, поэтому их селективность низкая (количество строк, деленное на количество различных значений этого столбца). Эти индексы - пустая трата пространства.

Некоторые вещи тоже не имеют смысла. tinyint(4) - это на самом деле не делает его четырехзначным целым числом. Номер есть длина дисплея. tinyint равен 1 байту, поэтому он имеет 256 возможных значений. Я предполагаю, что там что-то пошло не так.

Кроме того, 10 гигабайт в размере всего за 75 тысяч записей? Как вы измерили размер? Кроме того, какое у вас оборудование?

Изменить в отношении вашего обновленного вопроса:

Существует много способов масштабирования баз данных. Я свяжу один SO вопрос / ответ, чтобы вы могли понять, что вы можете сделать: здесь это . Другая вещь, которую вы можете сделать, это получить лучшее оборудование. Обычно причиной медленных баз данных при увеличении их размера является подсистема жесткого диска и доступная память, оставленная для работы с набором данных. Чем больше оперативной памяти у вас есть - тем быстрее все это становится.

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

В конце концов, все сводится к тому, что вам нужно сделать и как вы это делаете. Поскольку вы не упомянули об этом, трудно дать оценку того, что вы должны сделать. Моим первым шагом к оптимизации, безусловно, было бы настроить экземпляр MySQL и создать резервную копию этой большой таблицы.

2 голосов
/ 22 июня 2011

Полагаю, вам нужно изменить некоторые столбцы.

Вы можете начать с уменьшения переменных var char.

image_src / video_src / video_image_src VARCHAR (500) - это слишком много, я думаю.(100 varchars достаточно, я бы сказал)

thread_title является текстом, но должно быть VARCHAR (200?), Если вы говорите мне то же самое с section_title

Хорошо, вот ваша проблема content longtext

Вам действительно нужен длинный текст здесь?longtext - до 4 ГБ пространства.Я думаю, что если вы измените этот столбец на текст, он будет намного меньше

    TINYTEXT    256 bytes    
    TEXT    65,535 bytes    ~64kb
    MEDIUMTEXT   16,777,215 bytes   ~16MB
    LONGTEXT    4,294,967,295 bytes ~4GB

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

0 голосов
/ 22 июня 2011

В дополнение к тому, что прокомментировал Майкл, медлительность может быть проблемой в зависимости от того, насколько хорошо оптимизированы запросы и соответствуют ли индексы. Я попытался бы найти некоторые из запросов виновников, которые занимают больше времени, чем вы надеетесь, и опубликовать здесь, на S / O, чтобы узнать, может ли кто-то помочь в оптимизации вариантов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...