tags:

views:

31

answers:

1

I have a fairly popular site that's now getting rammed with a lot of traffic, and I've been informed by my webhost that the following query is taking up to 2 seconds to run. My MySQL skills aren't that great, so I'm sure I'm doing something wrong, but I'm not sure what could be done to improve it.

For simplicity's sake, assume live_blueprints is a table with four fields:

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

I realize using a string (levelSlug) instead of an int (id) is a probably bad idea, so that's one of the things I'd like to fix. Basically what I'm trying to do with this query is grab the top 49 blueprints with unique solution strings. The live_blueprints table has ~550k rows, and I think that's the main cause of the problem. The way I understand it, is that the way this is written, it'll check all 550k rows, and then group them, and then chop off the top 49 to give to me... I'm just wondering if there's a way I could do this without it having to do so much work on the rows... Perhaps even by creating a second table of just "unique" solutions.

Anyway, here's the query right now:

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

Thanks for whatever help or insight you can provide!

Ok, so to answer some questions:

The only indexes on the table are on id and levelSlug. For starters, I'm going to add an index on solution.

I did an explain, so I think this is what you're looking for, levelID is the index for 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
A: 

What kind of indexes do you have on your table?

Cause, having an index on solution, solutionCoolness (in that order) should help a bit here.

With the where clauses you could even use an index with the columns levelSlug, isSolved, solution, solutionCoolness in that order to make it a little faster.

Either way, we need to know which indexes you have and it would help to see the explain of the query.

WoLpH
Ok I've added that stuff to the original post, and I renamed the all the properties to the real ones... I had originally simplified the field names to simplify things, but I think it just makes things more complicated in the long run... So solutionCoolness is now trackCount, for example.
Matt Rix
@Matt Rix: don't try to add an index on 1 column, add an index on all of the columns together. Using multiple indexes is a lot slower than using 1 index with multiple columns.
WoLpH
Ah ok, so in this case, I'd want an index on all four columns? Or just levelSlug and solution?
Matt Rix
Bah, sorry, another question. I've looked around everywhere but can't seem to find an answer. I'm using phpMyAdmin, and when I create an index on multiple fields, I have to provide the size of each field in the index. So for a mediumint (7), would the size be 7? Or is that size property something different entirely. Sorry if these questions are super basic.
Matt Rix
@Matt Rix: you can add an index on all four columns. But I suggest you read a little about indices so you understand what's happening :) The size is optional for mediumints, it is meant to reduce your index size since indexes can take up a lot of space.
WoLpH