当前位置: 首页 > 面试题库 >

为什么STRAIGHT_JOIN如此大幅度地改善了此查询,并且在SELECT关键字之后编写它意味着什么?

高增
2023-03-14
问题内容

我有以下MySql查询:

select t1.*
from Table1 t1
inner join Table2 t2
on t1.CommonID = t2.CommonID
where t1.FilterID = 1

运行大约需要30秒,这很奇怪,因为如果我注释掉join或where子句,它会花费不到一秒钟的时间:

select t1.*
from Table1 t1
where t1.FilterID = 1

要么

select t1.*
from Table1 t1
inner join Table2 t2
on t1.CommonID = t2.CommonID

每个过程不到一秒钟。

然后是STRAIGHT_JOIN关键字,在这里可以找到它的一个参考:http
:
//dev.mysql.com/doc/refman/5.0/en/join.html

STRAIGHT_JOIN与JOIN相似,不同之处在于总是在右表之前读取左表。这可以用于联接优化器将表以错误的顺序放置的那些(很少)情况。

什么?我可以写:

select t1.*
from Table1 t1
STRAIGHT_JOIN  Table2 t2
on t1.CommonID = t2.CommonID
where t1.FilterID = 1

并在不到一秒钟的时间内执行查询。

即使是陌生人,我也可以写:

select STRAIGHT_JOIN  t1.*
from Table1 t1
inner join Table2 t2
on t1.CommonID = t2.CommonID
where t1.FilterID = 1

只需不到一秒钟的时间,这种语法甚至看起来都不合法。

我想第二个例子意味着每写一个INNER JOIN都会使用STRAIGHT_JOIN,但是我找不到关于它的任何文档。

这是怎么回事,“联合优化器”如何导致如此相对较差的性能?我应该一直使用STRAIGHT_JOIN吗?我如何知道何时使用它?

Table1和Table2都有整数主键;FilterID是另一个表的外键;CommonID​​列都是第三张表的外键。它们都有索引。数据库引擎是InnoDB。

谢谢


问题答案:

这是怎么回事,“联合优化器”如何导致如此相对较差的性能?

STRAIGHT_JOIN强制表的连接顺序,因此table1在外循环和table2内循环中进行扫描。

优化器不是完美的(尽管还算不错),最可能的原因是过时的统计信息。

我应该经常使用吗 STRAIGHT_JOIN

不,仅当优化器错误时。这可能是因为您的数据分布严重偏斜或无法正确计算(例如,对于空间索引或全文索引)。

我如何知道何时使用它?

您应该收集统计信息,为这两种方式html" target="_blank">构建计划,并了解这些计划的含义。

如果看到:

  1. 自动生成的计划并非最佳方案,无法通过标准方式进行改进,

  2. STRAIGHT_JOIN版本更好,你了解它总是会和理解 ,为什么 它总是会

,然后使用STRAIGHT_JOIN



 类似资料:
  • 问题内容: 乔什·布洛赫(Josh Bloch)在“ 有效的Java ”项目“项目22:相比于非静态偏爱静态成员类”中,说: 非静态成员类的每个实例都与其包含类的封闭实例隐式关联。在非静态成员类的实例方法中,可以使用限定的this构造在封闭实例上调用方法或获取对封闭实例的引用。 他所说的“ 合格的结构” 是什么意思? 问题答案: 没有限定词,将递归。使用限定符时,将调用封闭实例的方法。

  • 问题内容: 这是什么? 这是有关警告,错误和注意事项的许多答案,这些警告,错误和注意事项在您对PHP进行编程时可能会遇到,并且不知道如何解决它们。这也是一个社区Wiki,因此邀请所有人参与添加并维护此列表。 为什么是这样? 诸如“已发送标题”或“呼叫非对象成员”之类的问题经常在堆栈溢出中弹出。这些问题的根本原因总是相同的。因此,这些问题的答案通常会重复它们,然后向OP显示在特定情况下应更改的行。这

  • 描述中说: 在2020-11-10之前的Rust模型箱中发现了一个问题。共享数据结构具有发送和同步特征的实现,而不考虑内部类型。 什么是模型板条箱?抱歉,如果它的愚蠢的问题,但我是新的CVE漏洞。

  • 问题内容: 今天,我遇到了一个有趣的SQL问题,尽管我想出了一个行之有效的解决方案,但我怀疑这是最佳还是最有效的答案。在这里,我请专家- 帮助我学习一些知识并改善查询条件!RDBMS是SQL Server 2008 R2,查询是SSRS报告的一部分,该报告将针对约100,000行运行。 本质上,我有一个ID列表,该ID可能具有多个与之关联的值,这些值是Yes,No或其他字符串。对于ID x,如果任

  • 问题内容: $(‘button’).click(function () { 我的问题:尽管我打了个电话,为什么它仍然会提醒下一个号码?就像:忽略下面的代码,然后继续下一个元素 问题答案: 除了引发异常外,没有其他方法可以停止或中断循环。如果您需要这种行为,该方法是错误的工具。 提前终止可以通过以下方式完成: 一个简单的循环 一… 圈 另一个阵列的方法:,,,和测试使用谓词返回truthy值的数组元

  • 我想创建一个