为什么这个查询太慢了?

时间:2011-01-09 18:27:54

标签: mysql sql query-optimization

此查询出现在mysql慢查询日志中:需要11秒。

INSERT INTO record_visits
( record_id, visit_day )
VALUES
( '567', NOW() );

该表有501043条记录,其结构如下:

CREATE TABLE IF NOT EXISTS `record_visits` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `record_id` int(11) DEFAULT NULL,
  `visit_day` date DEFAULT NULL,
  `visit_cnt` bigint(20) DEFAULT '1',
  PRIMARY KEY (`id`),
  UNIQUE KEY `record_id_visit_day` (`record_id`,`visit_day`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 ;

可能有什么不对?为什么这个INSERT需要这么长时间?

更新

我发现了,所有麻烦的原因是什么。在该表上创建了一个非常繁重的“ON INSERT”触发器。与MyISAM表锁定一起,它为INSERT查询提供了大量的查询时间。可能这就是@Oswald在评论中无法重现这种情况的原因。

真正的问题是MySQL不会在触发器内部记录查询,并且在分析应用程序时总是要记住它们。

感谢大家的帮助,接受解决方案的答案。

3 个答案:

答案 0 :(得分:2)

我怀疑查询本身并不慢,但是你正在锁定表的服务器上运行其他查询。 MyISAM使用表级锁定,因此需要给定表的查询将锁定需要该表的所有其他查询,即使它们触及不同的行。例如,如果您经常有长时间运行的SELECT查询,那么在您发出查询完成后所有选择都运行之前,您的INSERT,UPDATE和DELETE查询将无法执行。

如果在插入运行时从另一个提示符中说SHOW PROCESSLIST,您可能会看到它处于“已锁定”状态。如果结果是另一个状态,并且没有长时间选择阻止它,你应该发布,因为这也有助于缩小问题范围。

答案 1 :(得分:1)

我认为,当您尝试向此表添加数据时,由于UNIQUE索引,mysql会检查所有 record_id_visit_day 行。

答案 2 :(得分:0)

我不知道MySQL,但是UNIQUE KEY是否意味着visit_day列上有索引?如果没有,请尝试创建一个。