mysql 前30秒_mysql – 简单查询需要15-30秒
以下查詢非常簡單.它從消息表中選擇最后20條記錄,以便在分頁方案中使用.第一次運行此查詢時,需要15到30秒.后續運行只需不到一秒鐘(我預計會涉及一些緩存).我試圖確定為什么第一次這么長時間.
這是查詢:
SELECT DISTINCT ID,List,`From`,Subject, UNIX_TIMESTAMP(MsgDate) AS FmtDate
FROM messages
WHERE List='general'
ORDER BY MsgDate
LIMIT 17290,20;
MySQL版本:4.0.26-log
這是表格:
messages CREATE TABLE `messages` (
`ID` int(10) unsigned NOT NULL auto_increment,
`List` varchar(10) NOT NULL default '',
`MessageId` varchar(128) NOT NULL default '',
`From` varchar(128) NOT NULL default '',
`Subject` varchar(128) NOT NULL default '',
`MsgDate` datetime NOT NULL default '0000-00-00 00:00:00',
`TextBody` longtext NOT NULL,
`HtmlBody` longtext NOT NULL,
`Headers` text NOT NULL,
`UserID` int(10) unsigned default NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `List` (`List`,`MsgDate`,`MessageId`),
KEY `From` (`From`),
KEY `UserID` (`UserID`,`List`,`MsgDate`),
KEY `MsgDate` (`MsgDate`),
KEY `ListOnly` (`List`)
) TYPE=MyISAM ROW_FORMAT=DYNAMIC
這是解釋:
table type possible_keys key key_len ref rows Extra
------ ------ ------------- -------- ------- ------ ------ --------------------------------------------
m ref List,ListOnly ListOnly 10 const 18002 Using where; Using temporary; Using filesort
當我在所有相關列上都有索引時,為什么使用filesort?我添加了ListOnly索引,看看它是否有用.我原本以為List索引會處理列表選擇和MsgDate上的排序,但事實并非如此.現在我添加了ListOnly索引,這是它使用的索引,但它仍然在MsgDate上執行一個文件排序,這是我懷疑花了這么長時間.
我嘗試使用FORCE INDEX如下:
SELECT DISTINCT ID,List,`From`,Subject, UNIX_TIMESTAMP(MsgDate) AS FmtDate
FROM messages
FORCE INDEX (List)
WHERE List='general'
ORDER BY MsgDate
LIMIT 17290,20;
這似乎迫使MySQL使用索引,但它根本不會加速查詢.
以下是此查詢的說明:
table type possible_keys key key_len ref rows Extra
------ ------ ------------- ------ ------- ------ ------ ----------------------------
m ref List List 10 const 18002 Using where; Using temporary
更新:
我從查詢中刪除了DISTINCT.它根本沒有幫助.
我刪除了UNIX_TIMESTAMP調用.它也沒有影響性能.
我在我的PHP代碼中做了一個特例,這樣如果我檢測到用戶正在查看結果的最后一頁,我會添加一個WHERE子句,它只返回結果的最后7天:
SELECT m.ID,List,From,Subject,MsgDate
FROM messages
WHERE MsgDate>='2009-11-15'
ORDER BY MsgDate DESC
LIMIT 20
這要快得多.但是,只要我導航到另一個結果頁面,它就必須使用舊的SQL并且需要很長時間才能執行.我想不出一個實用,現實的方法來為所有頁面執行此操作.此外,這種特殊情況使我的PHP代碼更加復雜.
奇怪的是,只有第一次運行原始查詢需要很長時間.后續運行相同的查詢或顯示不同結果頁面的查詢(即,只有LIMIT子句發生變化)非常快.如果查詢尚未運行約5分鐘,則查詢會再次變慢.
解:
我想出的最佳解決方案是基于Jason Orendorff和Juliet的想法.
首先,我確定當前頁面是否更接近總頁數的開頭或結尾.如果它更接近結尾,我使用ORDER BY MsgDate DESC,應用適當的限制,然后反轉返回記錄的順序.
這使得檢索頁面接近結果集的開頭或結尾的速度要快得多(第一次現在需要4-5秒而不是15-30秒).如果用戶想要導航到中間附近的頁面(當前在第430頁左右),那么速度可能會下降.但那是一種罕見的情況.
因此,雖然似乎沒有完美的解決方案,但這比大多數情況要好得多.
謝謝你,杰森和朱麗葉.
總結
以上是生活随笔為你收集整理的mysql 前30秒_mysql – 简单查询需要15-30秒的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 蚊香驱蚊原理是什么?
- 下一篇: java中类型转换的造型_Java-类型