数据库使用的是MySQL,引擎为MyISAM。
表定义如下:
CREATE TABLE IF NOT EXISTS matches (
id int(11) NOT NULL AUTO_INCREMENT,
game int(11) NOT NULL,
user int(11) NOT NULL,
opponent int(11) NOT NULL,
tournament int(11) NOT NULL,
score int(11) NOT NULL,
finish tinyint(4) NOT NULL,
PRIMARY KEY ( id ),
KEY game ( game ),
KEY user ( user ),
KEY i_gfu ( game , finish , user )
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3149047 ;
我在(game, finish, user)
上创建了一个索引,但这个GROUP BY
查询仍需要0.4-0.6秒才能运行:
SELECT user AS player
, COUNT( id ) AS times
FROM matches
WHERE finish = 1
AND game = 19
GROUP BY user
ORDER BY times DESC
EXPLAIN
输出:
| id | select_type | table | type | possible_keys | key | key_len |
| 1 | SIMPLE | matches | ref | game,i_gfu | i_gfu | 5 |
| ref | rows | Extra |
| const,const | 155855 | Using where; Using temporary; Using filesort |
有没有办法让它更快?这个表大约有800K条记录。
编辑:我将COUNT(id)
改为COUNT(*)
,时间降至0.08-0.12秒。我想在创建索引之前就尝试过这个方法,但忘记在之后再次更改了。
在explain输出中,Using index解释了加速的原因:
| rows | Extra |
| 168029 | Using where; Using index; Using temporary; Using filesort |
(旁问:因子5的下降是否正常?)
大约有2000个用户,因此即使使用文件排序,最终排序也不会影响性能。我尝试过不使用
ORDER BY
,但时间几乎相同。