【问题标题】:Joining three tables, than order, how to use index in MySql?连接三个表,比顺序,如何在MySql中使用索引?
【发布时间】:2018-09-03 09:45:00
【问题描述】:

我有这三个表:

season(id, season);
game_in_season(id, id_season, game);
player_in_game(id, id_game, full_name, pts);

我想选择索引为 5 的所有赛季球员并按 pts 排序。我应该使用哪个索引?我在 pg.pts 列上有一个索引,但是当我将表与 s 和 gs 表连接时不使用它。它仅在我制作“select * from pg order by pts desc”时使用。

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' 的一行中有额外的 = 'Using temporary;使用文件排序'。我应该使用哪个索引来不使用文件排序?甚至可以在不使用文件排序的情况下进行此查询吗?

【问题讨论】:

    标签: mysql join indexing


    【解决方案1】:

    请使用JOIN..ON 而不是逗号:

    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.id = 5 过滤s,或者在gs.id_season 上过滤gs gs.id_season = 5
    • 首先在pg 中使用INDEX(pts)(如果有的话)。

    前者必须在数据到达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

    【讨论】:

    • 感谢您的回答。我的问题是选择一个赛季的 player_in_games 行并按积分排序需要很长时间。选择所有 player_in_games 行并按点对它们进行排序要快得多(因为我在 pts 列上有一个索引,但在我指定季节时不使用它)。你知道如何解决它吗?我试图为每个季节制作一个视图,但我无法在视图中制作索引:(
    • A VIEW 只是语法糖;底层的SELECT 仍然需要优化和执行。 对于具有该表结构的查询没有解决方案。
    猜你喜欢
    • 2019-12-20
    • 1970-01-01
    • 2015-05-30
    • 2011-04-12
    • 2017-02-15
    • 1970-01-01
    相关资源
    最近更新 更多