Tom*_*Tom 5 mysql message-queue database-performance
是否有更快的方法来更新匹配特定条件的MySQL表的最旧行,而不是使用ORDER BY id LIMIT 1以下查询中的情况?
UPDATE mytable SET field1 = '1' WHERE field1 = 0 ORDER BY id LIMIT 1;
Run Code Online (Sandbox Code Playgroud)
注意:
id并且还有一个索引field1.id,即FIFO队列的头部.问题:
ORDER BY id必要吗?MySQL如何默认订购?我们有一个DB表用于电子邮件队列.当我们要将电子邮件排队以发送给我们的用户时,会添加行.行由cron作业删除,每分钟运行一次,在该分钟内尽可能多地处理并每行发送1封电子邮件.
我们计划放弃这种方法,并使用Gearman或Resque之类的东西来处理我们的电子邮件队列.但与此同时,我有一个问题,我们如何有效地标记队列中最旧的项目进行处理,即具有最低ID的行.此查询完成工作:
mysql_query("UPDATE email_queue SET processingID = '1' WHERE processingID = 0 ORDER BY id LIMIT 1");
Run Code Online (Sandbox Code Playgroud)
但是,由于扩展问题,它出现在mysql慢日志中很多.当表有500,000行时,查询可能需要10秒以上.问题是这个表自首次引入以来已经大量增长,现在有时有50万行,开销为133.9 MiB.例如,我们每天INSERT 6000个新行可能180次,并且删除大致相同的数字.
为了阻止查询出现在慢速日志中,我们删除了ORDER BY id以阻止整个表格的大规模.即
mysql_query("UPDATE email_queue SET processingID = '1' WHERE processingID = 0 LIMIT 1");
Run Code Online (Sandbox Code Playgroud)
...但是新查询不再总是获得id最低的行(尽管通常会这样).除了使用之外,是否有更有效的方法来获取id最低的行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;
Run Code Online (Sandbox Code Playgroud)