因此,我有两个表: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
视为内部表?我只是很好奇地看到同一个查询的两个不同执行之间如何比较。谢谢。
答案 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