我有一张用于计算 iPhone 游戏高分的表格。 截至目前,查询已禁用,因此玩家无法查看分数:-(
表具有以下字段:
Type Collation Attributes Null Default Extra Action
id int(11) No auto_increment
date date No
timestamp timestamp No CURRENT_TIMESTAMP
game_id tinyint(4) No
game_size tinyint(4) No
game_level tinyint(4) No
score float No
score_string char(11) utf8_general_ci No
name varchar(50) utf8_general_ci No
place varchar(50) utf8_general_ci No
device varchar(128) utf8_general_ci Yes NULL
我为 game_id 和 game_size 添加了两个字段索引 这可能是问题所在,但我不明白为什么搜索需要 5 分钟...
这是一个需要花费所有时间的查询。 其他更简单的查询也花费了很长时间。
SELECT SQL_CALC_FOUND_ROWS name, MIN(score_string) AS Expr1, place FROM
scores WHERE game_id="1" AND game_size = "5" AND game_level = "1"
AND date> "2005-04-14" GROUP BY name, place ORDER BY
MIN(score_string) Limit 0, 100;
当我在 phpMyAdmin 中测试它时,它返回 1 秒,然后返回几个 0.0015 秒,然后再次返回 1 秒。
我们非常欢迎任何帮助。 谢谢! 哈南
下面是建议查询的解释:
EXPLAIN SELECT name, score_string, place
FROM scores s
WHERE game_id =1
AND game_size =15
AND game_level =1
AND id = (
SELECT id
FROM scores si
WHERE si.game_id =1
AND si.game_size =15
AND si.game_level =1
AND si.name = s.name
AND si.place = s.place
AND si.date > '2005-04-14'
ORDER BY si.game_id, si.game_size, si.game_level, si.name, si.place, si.score_string, si.id
LIMIT 1
)
ORDER BY game_id, game_size, game_level, score_string, id
LIMIT 100
d select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY s ref game_id,indx1,game_id_2 game_id_2 3 const,const,const 14034 Using where
2 DEPENDENT SUBQUERY si ref game_id,indx1,game_id_2 game_id 307 const,const,const,tmi_hcg.s.name,tmi_hcg.s.place 13 Using where
显示创建表分数
CREATE TABLE `scores` (
`id` int(11) NOT NULL auto_increment,
`date` date NOT NULL,
`timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
`game_id` tinyint(4) NOT NULL,
`game_size` tinyint(4) NOT NULL,
`game_level` tinyint(4) NOT NULL,
`score` float NOT NULL,
`score_string` char(11) NOT NULL,
`name` varchar(50) NOT NULL,
`place` varchar(50) NOT NULL,
`device` varchar(128) default NULL,
PRIMARY KEY (`id`),
KEY `game_id` (`game_id`,`game_size`,`game_level`,`name`,`place`,`score_string`,`id`),
KEY `indx1` (`game_id`,`game_size`,`game_level`,`date`,`id`),
KEY `game_id_2` (`game_id`,`game_size`,`game_level`,`score_string`,`id`)
) ENGINE=MyISAM AUTO_INCREMENT=81564 DEFAULT CHARSET=utf8
似乎数据越接近今天,响应就越长:
SELECT name, score_string, place
FROM scores s
WHERE game_id =1
AND game_size =15
AND game_level =1
AND id = (
SELECT id
FROM scores si
WHERE si.game_id =1
AND si.game_size =15
AND si.game_level =1
AND si.name = s.name
AND si.place = s.place
AND si.date > "2010-10-01"
ORDER BY si.game_id, si.game_size, si.game_level, si.name, si.place, si.score_string, si.id
LIMIT 1 )
ORDER BY game_id, game_size, game_level, score_string, id
LIMIT 100
这花了 49 秒!
最佳答案
确保您有以下索引:
scores (game_id, game_size, game_level, date, id)
scores (game_id, game_size, game_level, name, place, score_string, id)
(根据数据分布,它们中的任何一个都可能有效)。
此外,添加以下索引可能会很有用:
scores (game_id, game_size, game_level, score_string, id)
并将查询重写为:
SELECT name, score_string, place
FROM scores s
WHERE game_id = 1
AND game_size = 5
AND game_level = 1
AND id =
(
SELECT id
FROM scores si
WHERE si.game_id = 1
AND si.game_size = 5
AND si.game_level = 1
AND si.name = s.name
AND si.place = s.place
AND si.date > '2005-04-14'
ORDER BY
si.game_id, si.game_size, si.game_level, si.name, si.place, si.score_string, si.id
LIMIT 1
)
ORDER BY
game_id, game_size, game_level, score_string, id
LIMIT 100
这些查询与第一个查询相同,但如果您的条件没有选择性,则更有用。
这两篇文章解释了查询的工作原理:
关于sql - MySQL查询有时还可以,其他时候需要5分钟!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3864229/