2012-04-13 108 views
0

我正在使用在Amazon RDS上具有MySQL數據庫的應用程序。在問題的表被設置爲這樣:MySQL表索引優化

CREATE TABLE `log` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `timestamp` datetime NOT NULL, 
    `username` varchar(45) NOT NULL, 
    .. snip some varchar and int fields .. 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

該系統已經在測試了一段時間,已經是數據集相當巨大,查詢開始是相當緩慢的。

SELECT COUNT(*) FROM log --> 16307224 (takes 105 seconds to complete) 

此表幾乎只用來建立一個報告過一個這樣的查詢

SELECT timestamp, username, [a few more] FROM log 
WHERE timestamp BETWEEN '2012-03-30 08:00:00' AND '2012-03-30 16:00:00' 
AND username='XX' 

通常會給服用100-180左右秒完成1000個6000行之間的東西,這意味着Web應用程序通常會超時並留下一個空的報告(我也會查看超時時間,但這個問題是出於根本原因)。

我對數據庫並不擅長,但我的猜測是,這是在這裏殺死我的間諜。我在想的是我應該以某種方式使用時間戳作爲索引。使用用戶名的時間戳應該仍然提供唯一性(我不使用任何id字段)。

如果有人在那裏提供優化建議,我全都耳熟能詳。

UPDATE:

表現變更爲以下

CREATE TABLE `log` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `timestamp` datetime NOT NULL, 
    `username` varchar(45) NOT NULL, 
    .. snip .. 
    `task_id` int(10) unsigned DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `index_un_ts` (`timestamp`,`username`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

SELECT聲明EXPLAIN返回的時間戳列和用戶ID下面

id => 1 
select_type => SIMPLE 
table => log 
type => range 
possible_keys => index_un_ts 
key => index_un_ts 
key_len => 55 
ref => 
rows => 52258 
Extra => Using where; Using index 
+0

您可以切換到MyISAM。例如,通過cron每日彙總數據並將其存儲在單獨的報告表中。 – 2012-04-13 08:43:52

回答

1

嘛指數會很有幫助。您需要能夠讀取EXPLAIN語句的輸出。

轉到MySQL和執行以下操作:

EXPLAIN SELECT timestamp, username, [a few more] FROM log 
WHERE timestamp BETWEEN '2012-03-30 08:00:00' AND '2012-03-30 16:00:00' 
AND username='XX' 

這個節目你MySQL用來執行查詢的計劃。將有列稱爲密鑰。這表明MySQL在查詢中使用了哪個索引。我懷疑你會在那裏看到所有的,這意味着MySQL從上到下掃描表,從而匹配你的where子句的每一行。現在在時間戳和用戶ID列上創建一個索引。再次運行EXPLAIN語句。您應該可以看到您在鍵列中創建的索引。

如果MySQL使用索引,那麼你的查詢應該快得多。請記住不要超過索引。索引使插入,更新和刪除更慢。當您向表中插入新行並且表中有三個索引時,新行必須將3個值寫入三個不同的索引。所以這是一把雙刃劍。

+0

哦,只是順便說一下,創建索引語句會運行一段時間,所以不要驚慌,如果它只是坐在那裏。它必須掃描entires表獲取值,然後將它們插入到新的索引結構中。索引是存儲在磁盤上的B樹或R樹,並與您的表保持同步。 – Namphibian 2012-04-13 08:26:42

+0

用openark套件改變你的桌子。 – 2012-04-13 08:45:42

+1

解釋確實帶回ALL。你會建議創建兩個索引,一個用於時間戳,一個用於用戶名,或者兩者的複合索引? – danneth 2012-04-13 08:47:53