我正在使用在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
您可以切換到MyISAM。例如,通過cron每日彙總數據並將其存儲在單獨的報告表中。 – 2012-04-13 08:43:52