我有这三个表:
season(id, season);
game_in_season(id, id_season, game);
player_in_game(id, id_game, full_name, pts);
我想选择索引为5的赛季所有球员,然后点击它们。我应该使用哪个索引?我在pg.pts列上有一个索引,但是当我用s和gs表连接表时它不会被使用。它仅在我通过pts desc"从pg顺序中选择*时使用。
EXPLAIN SELECT pg.* FROM season s, game_in_season gs, player_in_game pg
WHERE s.id = gs.id_season AND gs.id = pg.id_game
AND s.id = 5
ORDER BY pg.pts DESC
连续使用table =' s'有额外的='使用临时;使用filesort'。我应该使用哪个索引来不使用filesort?甚至可以在不使用filesort的情况下进行此查询吗?
答案 0 :(得分:0)
请使用JOIN..ON
代替commajoin:
SELECT pg.*
FROM season s
JOIN game_in_season gs ON s.id = gs.id_season
JOIN player_in_game pg ON gs.id = pg.id_game
WHERE s.id = 5
ORDER BY pg.pts DESC
优化器有两种执行方式:
s
过滤s.id = 5
,或者gs
上的gs.id_season
上等效过滤gs.id_season = 5
。INDEX(pts)
中使用pg
(如果有的话)。前必须在数据到达ORDER BY
后对其进行排序。优化器可能会采用这种方法。
后者效率低下因为它必须读取大量不必要的行,因为5
的测试来得太晚了。
Using temporary; Using filesort
似乎始终位于EXPLAIN
的第一行;这很令人困惑,因为
我假设你有这些索引(或PRIMARY KEYs
):
season: (id)
game_in_season: (id_season) -- Better would be (id_season, id)
player_in_game: (id_game)
底线:查询可能正在尽可能快地运行。
在提出效果问题时,请提供SHOW CREATE TABLE
和EXPLAIN
。