我有一个表user_notification。执行了一个执行
的cron命令SELECT * FROM `user_notification` `t` WHERE `t`.`status`=2;
其中状态1 - Send_fail,2- Queue,3- Success(像这样。)
在表格中,大约有100K记录,这些记录每天都呈指数级增长。此查询花费了太多时间。有没有办法优化这个查询?
#Table structure for table `user_notification`
CREATE TABLE `user_notification` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`notification_id` int(11) NOT NULL,
`notification_title` varchar(256) NOT NULL,
`notification_message` text NOT NULL,
`status` int(1) NOT NULL,
`created` int(11) NOT NULL,
`updated` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `user_notification`
ADD PRIMARY KEY (`id`),
ADD KEY `user_id` (`user_id`),
ADD KEY `notification_id` (`notification_id`);
ALTER TABLE `user_notification`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=94322;
ALTER TABLE `user_notification`
ADD CONSTRAINT `user_notification_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
ADD CONSTRAINT `user_notification_ibfk_2` FOREIGN KEY (`notification_id`) REFERENCES `notification` (`id`);
# Query_time: 0.010663 Lock_time: 0.000045 Rows_sent: 0 Rows_examined: 17294
SET timestamp=1491527264;
SELECT * FROM `user_notification` `t` WHERE `t`.`status`=2;
答案 0 :(得分:1)
正如其他人所提到的,在status
列上创建索引应该会有所帮助。
听起来你经常会在一个越来越大的表中使用相对较小的行子集(即“排队”行)。您可能想要考虑将“排队”记录放在他们自己的表中,然后将它们的状态更改为“成功”或“失败”时将它们移动到历史记录表中。这样,你只是从一张相对较小的桌子查询。当然,此策略涉及额外的删除和插入,因此可能会导致其他问题,具体取决于应用程序的工作方式。
答案 1 :(得分:0)
您的查询仅在0.01秒内执行,这非常快。如果你想要优化它,你可以做几件事。首先,您每次都需要所有8列吗?而不是使用
SELECT *
FROM user_notification t
WHERE t.status=2;
您应该始终只列出您实际需要的字段:
SELECT user_id, notification_id, notification_title, notification_message, status /*change columns as needed*/
FROM user_notification t
WHERE t.status=2;
除此之外,您可以为列状态创建索引以加快查询过滤。
ALTER TABLE user_notification
CREATE NONCLUSTERED INDEX i1 ON user_notification (status);
答案 2 :(得分:0)
在列status
上创建索引可以解决您的问题。
答案 3 :(得分:0)
"不要排队,只需这样做。"
认为MySQL是一个很好的排队系统是一个常见的错误。
如果排队和出列项目的麻烦近似于简单地执行任务的努力,那么就这样做。
好的,好的,你坚持排队吗?然后要么像杰拉德所说的那样做。或者也许只是有一个额外的桌子上的东西"等待完成"。
在轮询某些事情时,请务必注意事务性问题 - 否则两个线程可能会抓取并处理同一项目。
为什么在慢速日志中显示0.01s查询?可能你打开了log_queries_not_using_indexes
。 (我发现这个设置实际上没用,只是在慢速日志中混乱。)