加入三个表,比命令,如何在MySql中使用索引?

时间:2018-03-25 00:09:48

标签: mysql join indexing

我有这三个表:

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的情况下进行此查询吗?

1 个答案:

答案 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的第一行;这很令人困惑,因为

  • 通常在处理过程中会出现这种情况;和
  • 这种排序经常发生在RAM中,而不是发生在"文件中。或者是真实的"临时的"表。也就是说,你(以及许多其他MySQL用户)不应该被这种'额外'。
  • 吓到。

我假设你有这些索引(或PRIMARY KEYs):

season:          (id)
game_in_season:  (id_season) -- Better would be (id_season, id)
player_in_game:  (id_game)

底线:查询可能正在尽可能快地运行。

在提出效果问题时,请提供SHOW CREATE TABLEEXPLAIN