代码之家  ›  专栏  ›  技术社区  ›  CuriousLearner

MySQL-如何强制更改内部连接的评估顺序?

  •  1
  • CuriousLearner  · 技术社区  · 6 年前

    我有这两张桌子:A桌和B桌。在对这些表进行简单的内部联接时,

    SELECT *
    FROM tableA 
    JOIN tableB
    ON tableA.columnA = tableB.id
    

    现在, tableA 包含29000多行,而 tableB 仅包含11000多行。 tableB.id 是主键,因此是群集的。并且存在一个非聚集索引 columnA .

    根据我的想法,查询优化器应该 塔布莱 作为执行联接时的内部表,因为它的行数较少,并且 作为外部表,因为许多行需要从 基于 表ID 列。

    但事实上恰恰相反。出于某种原因,查询优化器正在处理 作为内桌和 塔布莱 作为外桌。

    有人能解释一下为什么会发生这种情况吗?我在思考过程中犯了什么错误?另外,是否有一种方法可以强制取代查询优化器的决策并命令它处理 塔布莱 作为内桌?我只是好奇地想看看同一个查询的两个不同的执行是如何相互比较的。谢谢。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Bill Karwin    6 年前

    在InnoDB中,主键索引查找的效率略高于二级索引查找。优化器可能更倾向于运行查找 tableB.id 因为它使用主键索引。

    如果要重写优化器重新排序表的能力,可以使用优化器提示。将按您在查询中指定的顺序访问表。

    SELECT *
    FROM tableA 
    STRAIGHT_JOIN tableB
    ON tableA.columnA = tableB.id
    

    该语法适用于任何当前支持的MySQL版本。

    这将使您有机会使用两种表顺序对查询进行计时,并查看哪种查询实际上运行得更快。

    MySQL8.0中还有新的语法来指定具有更大控制权的连接顺序: https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html#optimizer-hints-join-order