如何使这个MySQL SELECT + GROUP BY查询更有效?

时间:2010-10-23 21:22:09

标签: mysql group-by

我有一个相当受欢迎的网站,现在正在遭受大量流量的冲击,我的网站管理员已经通知我以下查询最多需要2秒才能运行。我的MySQL技能不是很好,所以我确定我做错了什么,但我不确定如何改进它。

为简单起见,假设live_blueprints是一个包含四个字段的表:

  • isSolved [tinyint(1)]
  • levelSlug [varchar(128)]
  • solution [varchar(255)]
  • trackCount [mediumint(7)]

我意识到使用字符串(levelSlug)而不是int(id)可能是一个坏主意,所以这是我想要解决的问题之一。基本上我正在尝试使用唯一解决方案字符串获取前49个蓝图。 live_blueprints表有大约550k行,我认为这是问题的主要原因。我理解它的方式是,这是写的方式,它会检查所有550k行,然后将它们分组,然后砍下前49给我...我只是想知道是否有办法我可以做到这一点,而不必在行上做那么多工作......也许甚至可以创建一个只有“独特”解决方案的第二个表。

无论如何,这是现在的查询:

SELECT * 
  FROM live_blueprints
 WHERE levelSlug = 'someLevelSlug' 
    && isSolved = 1 
GROUP BY solution 
ORDER BY trackCount ASC 
   LIMIT 49

感谢您提供的任何帮助或见解!

好的,回答一些问题:

表上唯一的索引是id和levelSlug。对于初学者,我将在解决方案上添加一个索引。

我做了解释,所以我认为这就是你要找的东西,levelID是levelSlug的索引。

id > 1
select_type > SIMPLE
table > live_blueprints
type > ref
possible_keys > levelID
key > levelID
key_len > 386
ref > const
rows > 4407
Extra > Using where; Using temporary; Using filesort

2 个答案:

答案 0 :(得分:0)

你桌上有什么样的索引?

因为,solution, solutionCoolness上的索引(按此顺序)应该有所帮助。

使用where子句,您甚至可以按顺序使用包含levelSlug, isSolved, solution, solutionCoolness列的索引,以使其更快一些。

无论哪种方式,我们都需要知道您拥有哪些索引,这有助于查看查询的explain

答案 1 :(得分:0)

如何添加另一列,让我们称之为排名只会供您使用。 添加新解决方案时,如果已存在,则将此列设为零,否则插入1或其他类似轨道计数的内容。 通过这种方式,您可以通过排名不为0的跟踪数来消除该组。