我该如何优化这个MySQL查询?

时间:2009-07-30 09:43:33

标签: php sql optimization mysql

我在包含超过370,000,000(是,三十七万)行的数据库的PHP脚本中使用以下MySQL查询。我知道这是非常耗费资源的,运行这一个查询需要很长时间。有谁知道如何优化查询或以更快的方式获取信息?

表格信息:

games | longint, unsigned, Primary Key
win   | bit(1)
loss  | bit(1)

查询:

SELECT MID(game,{$len},1) AS move,
       COUNT(*) AS games,
       SUM(win) AS wins,
       SUM(loss) AS losses
FROM games
WHERE game>{$something} AND game<{$something_else}
GROUP BY move

提前感谢您的帮助!

7 个答案:

答案 0 :(得分:5)

我可以做的唯一建议是使用表来预先计算每个游戏的所有计数总和,并在表游戏使用触发器进行更改。

答案 1 :(得分:1)

直接关闭,我将停止在SELECT表达式和GROUP BY中使用MID()查询。根据您的查询条件,MySQL在解析时不一定会在单个表达式中缓存它,所以至少试试这个:

SELECT MID(game,{$len},1) AS move,
   COUNT(*) AS games,
   SUM(win) AS wins,
   SUM(loss) AS losses
   FROM games WHERE game LIKE '{$game}%' GROUP BY move;

这不是世界上最大的变化,但它应该会产生一点点差异。除此之外,我认为,优化这种改变存储数据方式的唯一方法是预先计算这些值并在游戏结束时增加它们。

答案 2 :(得分:0)

我会尝试使用EXPLAIN查询或profiling

答案 3 :(得分:0)

如果您阅读量很大,请考虑在您常用的数据上保留并维护一个聚合表。

答案 4 :(得分:0)

对我而言,就像你可以对此进行非规范化并创建一个“移动”表,记录每次“移动”的统计数据,而不仅仅是“游戏”。

答案 5 :(得分:0)

您可以通过牺牲存储空间或保留存储空间来“购买速度”,但性能会更差。由于你的问题是速度,你需要一些预先计算。是的,对查询进行了一些分析。

BTW,“大型”曾经为OLTP(实时提供实际交易)和DW(分析大量数据)提供不同的配置(不同的硬件和设置)。

答案 6 :(得分:0)

mid()函数正在杀死此查询。 MySQL必须在内存中创建一个临时表来处理mid()函数,并且因为group by而在该表上执行filesort。

我假设$ game是游戏的类型。 (跳棋,国际象棋,tic tac toe)

我会为这种类型的游戏挂掉另一张桌子。这允许您的组使用更快的索引。

我建议像:

[game]
game bigint unsigned
win bit
loss bit
game_type_id bigint unsigned

[game_type]
game_type_id bigint unsigned
game_type_desc varchar(13)

小心这个大表上的alters语句。 在发出更改之前始终进行备份。