2010-09-14 19 views
2

我有一個約30萬行(並且不斷增長!)的表格,目前我有一些簡單的範圍選擇問題。MySQL:哪些索引用於簡單範圍選擇?

查詢,看起來像這樣的:

SELECT SUM(CEIL(dlvSize/100)) as numItems 
FROM log 
WHERE timeLogged BETWEEN 1000000 AND 2000000 
AND user = 'example'</pre> 

它需要時間才能完成,我認爲,解決辦法是在我使用的索引。下面是結果解釋:

+----+-------------+-------+-------+---------------------------------+---------+---------+------+----------+-------------+ 
| id | select_type | table | type | possible_keys     | key  | key_len | ref | rows  | Extra  | 
+----+-------------+-------+-------+---------------------------------+---------+---------+------+----------+-------------+ 
| 1 | SIMPLE  | log | range | PRIMARY,timeLogged    | PRIMARY | 4  | NULL | 11839754 | Using where | 
+----+-------------+-------+-------+---------------------------------+---------+---------+------+----------+-------------+ 

我的表結構是這樣的一個(減少以使其更適合對這個問題):

CREATE TABLE IF NOT EXISTS `log` (
    `origDomain` varchar(64) NOT NULL default '0', 
    `timeLogged` int(11) NOT NULL default '0', 
    `orig` varchar(128) NOT NULL default '', 
    `rcpt` varchar(128) NOT NULL default '', 
    `dlvSize` varchar(255) default NULL, 
    `user` varchar(255) default NULL, 
    PRIMARY KEY (`timeLogged`,`orig`,`rcpt`), 
    KEY `timeLogged` (`timeLogged`), 
    KEY `orig` (`orig`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

的我能做些什麼來優化這個查詢任何想法或索引在我的桌子上?

回答

3

你可能想嘗試加入composite index(user, timeLogged)

CREATE TABLE IF NOT EXISTS `log` (
    ... 
    KEY `user_timeLogged` (user, timeLogged), 
    ... 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

相關堆棧溢出後:

+2

這樣,您也可以將索引放在'timeLogged'上,因爲它已經參與了主鍵的左側。 – bobince 2010-09-14 14:59:59

+0

謝謝,這將查詢時間縮短到不到1分鐘。我會繼續搜索其他選項,因爲我希望至少在10秒內完成此操作。 – Fernando 2010-09-14 20:22:20

+0

爲什麼不是'timeLogged_user(timeLogged,user)'的關鍵。我認爲索引工作從左到右? – 2014-04-03 02:20:41

0

user添加一個索引。

+1

丹尼爾在(用戶,時間記錄)上添加索引的建議可能是最好的(回想'(A,B)'上的索引也可以用作'(A)'的索引)。 – Hammerite 2010-09-14 14:51:41

+0

嗯,timepal已經被索引爲主鍵,因此也可能不需要在組合索引中使用額外的開銷。與往常一樣,測試是驗證此類問題的最佳方法。 – RedFilter 2010-09-14 15:02:38

1

除了其他答案所提出的建議外,我注意到表中有一列user,它是varchar(255)。如果這涉及到用戶表中的列,那麼1)將整數ID列添加到該表最有效,並將其用作主鍵和其他表中的引用列; 2)您使用InnoDB,那麼爲什麼不利用它提供的外鍵功能?

請注意,如果索引varchar(n)列,則它在索引中被視爲char(n),因此當前主鍵的每一行在索引中佔用4 + 128 + 128 = 260個字節。