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

标签 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 视为外表,因为需要根据 tableB.id 列的值从 tableA 中筛选出很多行。

但是,实际情况恰恰相反。出于某种原因,查询优化器将 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

关于mysql - 如何强制更改内部联接的评估顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53822147/

相关文章:

javascript - PHP:AJAX 请求时出现 500 内部服务器错误

查询 JSON 对象时 MySQL 查询超时

mysql - 通过数据透视表检查数据库中是否存在关系

MySQL跨多个表计数并获得单个值

mysql - 将设计拆分为父表和子表,或者拥有一个包含所有数据的表

php - 通过PHP的sql查询总是跳过第一行

Mysql不在大表上使用索引

mysql - 我怎样才能简化/提高这个 MySQL 查询的性能?

mysql - 内连接 - 单独的列

php - OSTicket - 未知或无效的架构签名