我不明白为什么以下查询需要这么长时间才能排序。在分析中,它表明排序需要很长时间,即使排序行有索引。
MySQL服务器是一台专用机器,在当前Debian稳定版本中基本上只运行MySQL,具有32 GB物理RAM和一个不错的MySQL配置。表player
(INNODB)目前有大约32,000,000个条目。表player
的索引:
gameplayer
超过game, id, server
(唯一)
serverplayer
超过id, server
(索引)
date
超过date
(索引)< - 这就是我们要排序的
以下查询用于获取有关特定玩家的游戏统计数据,从而获取有关玩家,统计数据和实际游戏的信息:
set profiling = 1;
SELECT *
FROM `player` `gs`
INNER JOIN `playerstats` `gss` ON (`gss`.`player` = `gs`.`id`)
INNER JOIN `game` `g` ON (`g`.`id` = `gs`.`game`)
WHERE `gs`.`id` = :id
AND `gs`.`server` = :server
ORDER BY `gs`.`date` DESC
LIMIT 10;
show profile for query 1;
set profiling = 0;
以下是展示资料的结果:
starting 0.000124
Waiting for query cache lock 0.000070
checking query cache for query 0.000090
checking permissions 0.000066
checking permissions 0.000058
checking permissions 0.000056
Opening tables 0.000074
System lock 0.000058
Waiting for query cache lock 0.000093
init 0.000071
optimizing 0.000054
statistics 0.000136
preparing 0.000073
executing 0.000044
Sorting result 0.201156 // <========================
Sending data 0.042253
end 0.000046
query end 0.000038
closing tables 0.000043
freeing items 0.000042
Waiting for query cache lock 0.000037
freeing items 0.000039
Waiting for query cache lock 0.000035
freeing items 0.000032
storing result in query cache 0.000031
logging slow query 0.000030
cleaning up 0.000031
如果我理解MySQL正确,那么它应该使用WHERE条件的serverplayer
索引和排序的date
索引,对吧?那么,为什么我需要适当的索引时需要这么长时间?
或者我是否必须将列date
添加到serverplayer
索引?
答案 0 :(得分:1)
请阅读此链接了解详情:http://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html
在您的特定情况下,此条件不符合,MySql不使用索引来排序行:
在某些情况下,MySQL 虽然它仍然使用,但不能使用索引来解析ORDER BY 索引以查找与WHERE子句匹配的行。这些案件 包括以下内容:
....用于获取行的密钥是 与ORDER BY
中使用的不一样:
SELECT * FROM t1 WHERE key2=constant ORDER BY key1;
...... ......
但是,当创建列id + server + date
上的索引时,id
和date
是WHERE子句中用于选择行的列,date
是索引中的最后一列,上述条件不适用,MySql可以使用此索引对行进行排序,避免使用filesort。