2017-04-07 65 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。 (我發現這個設置實際上是無用的,只是在緩慢的日誌中混亂。)