Есть ли более быстрый способ обновить самую старую строку таблицы MySQL, которая соответствует определенному условию, чем использование ORDER BY id LIMIT 1
, как в следующий запрос?
UPDATE mytable SET field1 = '1' WHERE field1 = 0 ORDER BY id LIMIT 1;
Примечание:
id
, а также есть индекс в field1
. идентификатор
, то есть заголовок очередь FIFO. Вопросы:
ORDER BY id
? Как MySQL упорядочивает по умолчанию? У нас есть таблица БД, которая используется для очереди электронной почты. Строки добавляются, когда мы хотим поставить электронные письма в очередь для отправки нашим пользователям. Строки удаляются заданием cron, запускаются каждую минуту, обрабатывая как можно больше за эту минуту и отправляя по одному электронному письму на строку.
Мы планируем отказаться от этого подхода и использовать что-то вроде Gearman или ] Resque для обработки нашей очереди электронной почты. Но пока у меня есть вопрос, как мы можем эффективно отметить самый старый элемент очереди для обработки, он же Строка с наименьшим идентификатором. Этот запрос выполняет свою работу:
mysql_query("UPDATE email_queue SET processingID = '1' WHERE processingID = 0 ORDER BY id LIMIT 1");
Однако он часто появляется в журнале медленных запросов MySQL из-за проблем с масштабированием. Запрос может занять более 10 секунд, если таблица содержит 500 000 строк. Проблема в том, что эта таблица значительно выросла с тех пор, как она была впервые представлена, и теперь иногда имеет полмиллиона строк и накладные расходы в 133,9 МБ. Например, мы ВСТАВЛЯЕМ 6000 новых строк, возможно, 180 раз в день и УДАЛЯЕМ примерно такое же количество.
Чтобы запрос не появлялся в журнале медленных операций, мы удалили ORDER BY id
, чтобы остановить массовую сортировку весь стол. т.е.
mysql_query("UPDATE email_queue SET processingID = '1' WHERE processingID = 0 LIMIT 1");
... но новый запрос больше не всегда получает строку с наименьшим идентификатором (хотя это часто бывает). Есть ли более эффективный способ получить строку с наименьшим идентификатором, кроме использования ORDER BY id
?
Для справки: это структура таблицы очереди сообщений электронной почты:
CREATE TABLE IF NOT EXISTS `email_queue` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`time_queued` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Time when item was queued',
`mem_id` int(10) NOT NULL,
`email` varchar(150) NOT NULL,
`processingID` int(2) NOT NULL COMMENT 'Indicate if row is being processed',
PRIMARY KEY (`id`),
KEY `processingID` (`processingID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;