ype*_*eᵀᴹ 6 mysql myisam group-by query-optimization
数据库是带有MyISAM引擎的MySQL.
表定义:
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 ;
Run Code Online (Sandbox Code Playgroud)
我已设置索引,(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
Run Code Online (Sandbox Code Playgroud)
的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 |
Run Code Online (Sandbox Code Playgroud)
有什么方法可以让它更快吗?该表有大约800K的记录.
编辑:我改变COUNT(id)
了COUNT(*)
,时间下降到0.08 - 0.12秒.我想在制作索引之前我已经尝试过了,之后忘了再次更改它.
在explain输出中,Using索引解释了加速:
| rows | Extra |
| 168029 | Using where; Using index; Using temporary; Using filesort |
Run Code Online (Sandbox Code Playgroud)
(旁边的问题:这是正常的5倍下降吗?)
大约有2000个用户,所以最后排序,即使它使用filesort,也不会影响性能.我试过没有ORDER BY
,它仍然需要几乎相同的时间.
摆脱'游戏'键 - 它与'i_gfu'是多余的.由于'id'是唯一计数(id),因此只返回每个组中的行数,因此您可以删除它并将其替换为count(*).尝试这种方式并粘贴EXPLAIN的输出:
SELECT user AS player, COUNT(*) AS times
FROM matches
WHERE finish = 1
AND game = 19
GROUP BY user
ORDER BY times DESC
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
7345 次 |
最近记录: |