2017-04-07 56 views
0

我有一个表user_notification。有一个cron命令运行的执行如何优化我的sql查询

SELECT * FROM `user_notification` `t` WHERE `t`.`status`=2; 

,其中状态1 - Send_fail,2-队列,3-成功(像这样)

在表中有大约10万〜记录被成倍增加一天白天。这个查询花费了太多时间。有没有一种方法来优化这个查询?

#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; 
+1

查询执行时间为0.01秒。这还不错,但您仍然可以在列状态下创建索引。 –

+0

@Manish为什么你在查询中使用't' SELECT * FROM user_notification t WHERE t.status = 2;'我认为没有必要使用'aliases' – user3441151

+2

@ user3441151。 。 。别名通常是一个好主意,不应该气馁。 –

回答

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); 
0

在列status上创建索引应解决您的问题。

1

正如其他人所说,在status列上创建索引应该有所帮助。

这听起来像你将经常在一个日益庞大的表格中使用相对较小的行子集(即“排队”行)。您可能需要考虑将“排队”记录放入自己的表中,然后将它们的状态更改为“成功”或“失败”,然后将它们移动到历史记录表中。这样,你只能从一个相对较小的表中查询。当然,这个策略需要额外的删除和插入,所以它可能会导致其他问题,这取决于你的应用程序的工作方式。

0

“不要排队,只是做它。”

认为MySQL创建了一个很好的排队系统是一个常见的错误。

如果排队和排队项目的麻烦近似于简单执行任务的努力,那就这样做。

好的,好的,你坚持要排队吗?然后按Jerrad的建议去做。或者也许只是有一个额外的桌子,“等待完成”。

当轮询某件事情时,一定要注意事务性问题 - 否则两个线程可能会抓住并处理同一个项目。

为什么在缓慢日志中显示0.01秒查询?可能你打开log_queries_not_using_indexes。 (我发现这个设置实际上是无用的,只是在缓慢的日志中混乱。)