优化表格以提高性能

时间:2014-08-14 15:16:42

标签: mysql queue innodb database-performance

对于我使用的简单解析器,我有2个表

CREATE TABLE IF NOT EXISTS `parsers` (
  `parser_id` int(11) NOT NULL AUTO_INCREMENT,
  `last_used` datetime NOT NULL,
  `engine_id` int(11) NOT NULL,
  `job_id` varchar(20) DEFAULT NULL,
  `notice` text NOT NULL,
  PRIMARY KEY (`parser_id`),
  KEY `last_used_2` (`last_used`,`parser_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=167541 ;

CREATE TABLE IF NOT EXISTS `engines` (
  `engine_id` int(11) NOT NULL AUTO_INCREMENT,
  `ip` varchar(50) NOT NULL,
  `status` int(11) NOT NULL,
  `in_use` int(11) NOT NULL,
  `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`engine_id`),
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1201 ;

这基本上是一个解析器队列。以下查询将作业分配给解析器

UPDATE parsers SET job_id = '$job_id', last_used = NOW() WHERE job_id IS NULL AND status = 1 AND engine_id IN(SELECT engine_id FROM engines WHERE in_use = 0) ORDER BY last_used ASC

然后获取分配的工作以进行进一步处理:

SELECT * FROM parsers WHERE job_id = '$job_id'

我的问题是,当多个解析器在查询上处于活动状态时,UPDATE查询变得非常慢,查询有时需要10秒才能执行,这是不可接受的,因为它会大大减慢所有内容。

EXPLAIN显示using where;using filesort,我认为该漏洞位于using filesort

我认为添加索引可以解决这个问题并加快查询速度。

我尝试添加ALTER TABLE parsers ADD INDEX(last_used,parser_id)一段时间改善了性能,同时也让using filesort消失了但是今天我再次检查using filesort又回来了,表现一如既往之前。 该指数是否正确?我怎样才能提速?

1 个答案:

答案 0 :(得分:0)

索引的一般规则是,您需要它们来涵盖WHERE条件,如果它很重要,请在之后包含与ORDER相关的任何内容。

在您的情况下,您需要一个涵盖parser_id的索引,因为这是查询中唯一存在的内容。 last_used,parser_id上的索引对此查询无效。

作为一个说明,如果您正在尝试在MySQL中构建一个作业队列并且需要最大的性能,那么您将面临一场艰苦的战斗。更好的选择包括RabbitMQ作为队列解决方案,或Redis作为高速数据库。