Suppose I have the following tables:
CREATE TABLE Game (
GameID INT UNSIGNED NOT NULL,
GameType TINYINT UNSIGNED NOT NULL,
PRIMARY KEY (GameID),
INDEX Index_GameType (GameType, GameID)
) ENGINE=INNODB
CREATE TABLE HighScore (
Game INT UNSIGNED NOT NULL,
Score SMALLINT UNSIGNED,
PRIMARY KEY (Game),
INDEX Index_Score (Score, Game),
CONSTRAINT Constr_Score_Game_fk
FOREIGN KEY Score_Game_fk (Game) REFERENCES Game (GameID)
) ENGINE=INNODB
(These are slimmed-down versions of real tables I am working with. The real tables have more columns and indexes. The above tables capture the essential features of the situation.)
(The number of different GameTypes should be assumed to be small, so that the index Index_GameType is not very selective.)
Suppose I run the following query:
SELECT
HighScore.Score
FROM
HighScore
JOIN Game ON HighScore.Game = Game.GameID
WHERE
Game.GameType = 42
ORDER BY
HighScore.Score DESC
LIMIT 50
Looking at this query and the table design, we can probably agree that the sensible thing would be to scan down the HighScore table and join rows until 50 have been found for which the WHERE condition is satisfied. However, an EXPLAIN for me showed (using my real, more complicated tables) that MySQL actually planned to look for all rows in Game satisfying the WHERE condition, join this with HighScore, and do a filesort to get the rows in sorted order.
It seemed sensible therefore to specify a STRAIGHT_JOIN instead in the above query. Now the EXPLAIN output indicates that the first table, HighScore, is "using index" (as expected), but the number of rows reported appears to be the number of rows in the HighScore table. Should I take this to mean that MySQL plans to take essentially the entire index, join every row in that index to the other table, and only then throw away rows below the top 50? That seems ridiculous, but I'm not sure if that's what it would actually do. Does anyone have any idea?