我試圖優化一個需要大約15-20秒才能運行的MySQL查詢。我的數據表有大約10M行,並且查詢試圖返回與144個「運行」字段和35個「名稱」字段匹配的68,000條記錄。因爲查詢使用了兩個子句,所以我的索引似乎不是非常有用。使用兩個「in」子句優化查詢
這裏的查詢:
select * from data d where
d.data_type='Result' and
(d.run in ('8a7aee1f2a6232b1012a624da9201b92', '8a7aee1f2a6232b1012a625432a314ef' ,
... [144 runs]
)) and (d.name like 'itema[%]' or d.name like 'itemb[%]')
這裏的表定義
CREATE TABLE `data` (
`data_type` varchar(31) NOT NULL,
`id` char(32) NOT NULL,
`entry_time` datetime default NULL,
`name` varchar(255) NOT NULL,
`step` int(11) default NULL,
`value` double NOT NULL,
`run` char(32) NOT NULL,
PRIMARY KEY (`id`),
KEY `FK2EEFAA8ECCC6F3` (`run`),
KEY `data2` (`run`,`step`),
KEY `data3` (`data_type`,`name(10)`,`run`),
CONSTRAINT `FK2EEFAA8ECCC6F3` FOREIGN KEY (`run`) REFERENCES `run_archive` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
解釋告訴我的查詢使用的關鍵數據3。
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE d range FK2EEFAA8ECCC6F3,data2,data3 data3 223 NULL 113271 Using where
我曾經運行過144次查詢(每次運行一次)。這似乎是做一個查詢的兩倍,但仍然太慢。
優化建議?想法我有【
找到一個神奇的索引速度
這件事反規範化的數據(這將會是 容易擺脫運行,但
更難名稱)分裂 不同的表中的數據 (很難與我的Java /休眠 進場做)
或者我只是問在這裏不可能?
編輯:原來最大的修復是增加我的innodb_buffer_pool的大小。這樣做後查詢下降到大約1秒半。我已經標記爲「回答」一個修正,稍微改進了一點。
什麼是where條款中的個人限制的選擇性?即數據類型'結果'有多少行,具有匹配運行的行數以及表中存在匹配名稱的行數? – meriton 2010-08-14 22:06:56
編輯:有data3鍵錯誤。 (我會交代)。第一個字段是data_type。 – 2010-08-14 22:08:08