У меня довольно большая таблица InnoDB, которая содержит около 10 миллионов строк (и подсчет, ожидается, что он станет в 20 раз больше). Каждая строка не такая большая (в среднем 131 B), но время от времени мне приходится удалять кусок из них, и это занимает много времени. Это структура таблицы:
CREATE TABLE `problematic_table` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`taxid` int(10) unsigned NOT NULL,
`blastdb_path` varchar(255) NOT NULL,
`query` char(32) NOT NULL,
`target` int(10) unsigned NOT NULL,
`score` double NOT NULL,
`evalue` varchar(100) NOT NULL,
`log_evalue` double NOT NULL DEFAULT '-999',
`start` int(10) unsigned DEFAULT NULL,
`end` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `taxid` (`taxid`),
KEY `query` (`query`),
KEY `target` (`target`),
KEY `log_evalue` (`log_evalue`)
) ENGINE=InnoDB AUTO_INCREMENT=7888676 DEFAULT CHARSET=latin1;
Запросы, которые удаляют большие куски из таблицы, выглядят следующим образом:
DELETE FROM problematic_table WHERE problematic_table.taxid = '57';
Для такого запроса потребовалось почти час, чтобы закончить. Я могу себе представить, что накладные расходы на переопределение индекса делают эти запросы очень медленными.
Я разрабатываю приложение, которое будет запускаться в уже существующих базах данных. Я, скорее всего, не могу контролировать переменные сервера, если я не вношу им необходимые изменения (чего я бы предпочел не делать), поэтому я боюсь, что предложения, которые меняют их, мало ценятся.
Я попытался INSERT ... SELECT
те строки, которые я не хочу удалять во временную таблицу, и просто отбрасываю остальное, но поскольку отношение to-delete vs. to-keep shifts to-keep, это уже не является полезным решением.
Это таблица, которая может видеть частые INSERT
и SELECT
в будущем, но не UPDATE
s. В принципе, это журнал и справочная таблица, которая время от времени должна отбрасывать часть своего контента.
Могу ли я улучшить свои индексы на этой таблице, ограничив их длину? Переключение на MyISAM-справку, которая поддерживает DISABLE KEYS
во время транзакций? Что еще я мог бы улучшить производительность DELETE
?
Изменить: Одно такое удаление будет порядка порядка миллиона строк.