mysql-如何强制更改内部联接的求值顺序?

时间:2018-12-17 19:55:13

标签: mysql query-optimization inner-join mysql-workbench

因此,我有两个表:tableA和tableB。在对这些表进行简单的内部联接后,

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

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

根据我的想法,查询优化器在执行连接时应将tableB视为内部表,因为它的行数较少,而将tableA视为外部表,需要根据tableA列的值从tableB.id中过滤掉许多行。

但是,实际上恰恰相反。由于某种原因,查询优化器将tableA视为内部表,并将tableB视为外部表。

有人可以解释为什么会发生这种情况,以及我在思考过程中犯了什么错误吗?另外,是否有一种方法可以强制取代查询优化器的决定,并要求其将tableB视为内部表?我只是很好奇地看到同一个查询的两个不同执行之间如何比较。谢谢。

1 个答案:

答案 0 :(得分:2)

在InnoDB中,主键索引查找的效率比次级索引查找略高。优化器可能更喜欢对tableB.id运行执行查找的联接,因为它使用主键索引。

如果要覆盖优化程序对表进行重新排序的功能,则可以使用优化程序提示。将按照您在查询中指定的顺序访问这些表。

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

该语法应在任何当前受支持的MySQL版本中起作用。

这将使您有机会按任一表顺序计时查询,并查看实际上哪个表运行得更快。

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