mysql - 连接三张表,比顺序,如何在MySql中使用索引?

标签 mysql join indexing

我有这三个表:

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

最佳答案

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

前者必须在到达ORDER BY 后对数据进行排序。优化器可能会选择这种方法。

后者效率低下,因为它必须读取大量不必要的行,因为 5 的测试来得太晚了。

使用临时的;使用filesort似乎总是在EXPLAIN的第一行;这是令人困惑的,因为

  • 通常在处理过程中进行排序;和
  • 排序通常发生在 RAM 中,而不是在"file"或真正的“临时”表中。也就是说,您(和许多其他 MySQL 用户)不应该被那个“Extra”吓到。

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

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

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

询问性能问题时,请提供SHOW CREATE TABLEEXPLAIN

关于mysql - 连接三张表,比顺序,如何在MySql中使用索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49471273/

相关文章:

mysql - 获取给定组的每种产品的最低价格

mysql - 我有一个用户表和金额表,即使金额为空或零,我也想向所有用户显示金额

python - 将级别附加到 pandas MultiIndex

JavaScript insertAt 位置

mysql - 我可以创建一个过程或函数来删除 mysql 中的参数表吗?

java - 在用Java为该应用程序编码应用程序时,如何存储主机地址,数据库的用户名和密码以及其他安全信息?

php - 找出多维数组的差异

php - 带有连接的搜索查询在搜索字符串为空时显示所有行

MySQL 后缀索引

PHP/MySQLi - 循环数组以构建动态 WHERE 子句