所以,我有两张桌子:桌子A和桌子B。在对这些表进行简单的内部连接时,
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
视为内部表?我只是想看看同一个查询的两个不同执行是如何相互比较的。谢谢。 最佳答案
在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