我有一個表,其中存儲pupil_id,類別和生效日期(除其他事項外)。日期可以是過去,現在或未來。我需要一個查詢來從表格中提取學生的當前狀態。我怎樣才能優化這個MySQL查詢?
以下查詢的工作原理:
SELECT *
FROM pupil_status
WHERE (status_pupil_id, status_date) IN (
SELECT status_pupil_id, MAX(status_date)
FROM pupil_status
WHERE status_date < NOW() -- to ensure we ignore the "future status"
GROUP BY status_pupil_id);
在MySQL,該表被定義如下:
CREATE TABLE IF NOT EXISTS `pupil_status` (
`status_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`status_pupil_id` int(10) unsigned NOT NULL, -- a foreign key
`status_category_id` int(10) unsigned NOT NULL, -- a foreign key
`status_date` datetime NOT NULL, -- effective date/time of status change
`status_modify` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`status_staff_id` int(10) unsigned NOT NULL, -- a foreign key
`status_notes` text NOT NULL, -- notes detailing the reason for status change
PRIMARY KEY (`status_id`),
KEY `status_pupil_id` (`status_pupil_id`,`status_category_id`),
KEY `status_pupil_id_2` (`status_pupil_id`,`status_date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1409 ;
然而,隨着950級的學生和剛剛超過1400點的狀態在表中,查詢採用0.185秒來處理。現在也許可以接受,但是當桌子膨脹時,我擔心可擴展性。生產系統可能會有超過10000名學生,每個學生都有15-20個狀態。
有沒有更好的方法來寫這個查詢?是否有更好的索引來幫助查詢?請告訴我。
謝謝!我沒有意識到在WHERE ... IN和INNER JOIN之間會有這麼令人難以置信的區別。與10000000名學生的200000個狀態,查詢返回0.08秒比上述查詢超過5分鐘(然後我厭倦了等待)的查詢。儘管我沒有改變鑰匙,但不確定它的必要性。 – Philip 2010-10-22 06:16:23