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

LEFT JOIN显着快于INNER JOIN

华英睿
2023-03-14
问题内容

我有一个表(MainTable),其中有600,000多条记录。它通过JoinTable父/子类型关系中的第二个表()连接到自身:

SELECT   Child.ID, Parent.ID
FROM     MainTable
AS       Child
JOIN     JoinTable
      ON Child.ID = JoinTable.ID
JOIN     MainTable
AS       Parent
      ON Parent.ID = JoinTable.ParentID
     AND Parent.SomeOtherData = Child.SomeOtherData

我知道每个子记录都有一个父记录,并且JoinTable中的数据是准确的。

当我运行此查询时,它实际上需要几分钟的时间。但是,如果我使用“左连接”加入“父级”,则运行时间不到1秒:

SELECT   Child.ID, Parent.ID
FROM     MainTable
AS       Child
JOIN     JoinTable
      ON Child.ID = JoinTable.ID
LEFT JOIN MainTable
AS       Parent
      ON Parent.ID = JoinTable.ParentID
     AND Parent.SomeOtherData = Child.SomeOtherData
WHERE    ...[some info to make sure we don't select parent records in the child dataset]...

我了解到INNER JOIN和之间的结果有所不同LEFT JOIN。在这种情况下,它返回的结果与每个孩子都有父母的情况完全相同。如果我让两个查询都运行,我可以比较数据集,它们是完全相同的。

为什么LEFT JOIN运行速度比运行速度快得多INNER JOIN

UPDATE检查查询计划,并在使用内部联接时从父数据集开始。进行左连接时,它从子数据集开始。

它使用的索引都是相同的。

我可以强迫它总是从孩子开始吗?使用左联接有效,只是感觉不对。


问题答案:

左联接似乎更快,因为强制SQL先执行较小的选择,然后再联接到此较小的记录集。由于某种原因,优化器不希望自然地这样做。

强制以正确顺序进行连接的3种方法:

  1. 选择第一个数据子集到临时表(或表变量)中,然后对其进行联接
  2. 使用左联接(请记住,这可能返回不同的数据,因为它是左联接而不是内部联接)
  3. 使用FORCE ORDER关键字。请注意,如果表大小或架构更改,则查询计划可能不正确(请参阅https://dba.stackexchange.com/questions/45388/forcing-join-order)


 类似资料:
  • 我有一个2.1.4版本的项目,带有spring boot数据。 该项目具有以下关系实体:ApplicationEntity ApplicationTranslateEntity LanguageEntity它在数据库中有一个区域设置关系表(ManyToMany),该表中有一个用于不同语言的文本的额外表(ApplicationTranslateEntity)。 org.hibernate.Query

  • 问题内容: 我有两张表。这是100,000行,也就是10,000行。 我需要将它们加入到一个名为的列上,这两个列都是VARCHAR(50)。order_number在出站表中不是唯一的。 这是我的初始查询,运行时间超过60秒: 此查询得到相同的结果,并且运行时间不到一秒钟: 这使我感到惊讶,因为通常子查询要慢得多。 运行(我仍在学习如何理解)显示,子查询版本使用表,使用索引,并且索引为。我不够聪明

  • 我正在阅读Java中的TCP/IP套接字,关于服务器套接字,它说 当我们在该ServerSocket实例上调用接受()时,如果新连接挂起,接受()立即返回;否则它会阻塞,直到连接进入或计时器到期,以先到者为准。这允许单个线程处理多个连接。不幸的是,这种方法要求我们不断轮询所有I/O源,而这种“忙等待”方法再次引入了大量开销,因为循环遍历连接只是为了发现它们无事可做。 据我所知,当连接到来时,是否应

  • 今天,我发现在添加了一些不相关的代码后,示例代码的速度降低了50%。调试后,我发现问题出在循环对齐中。根据循环代码的位置,有不同的执行时间,例如: 我以前没想到代码对齐会产生如此大的影响。我认为我的编译器足够聪明,可以正确对齐代码。 到底是什么导致了执行时间的如此大的差异?(我想是一些处理器架构细节)。 我用Visual Studio 2019在发布模式下编译的测试程序,并在Windows 10上

  • 我正在尝试使用KStream-KTable leftJoin来丰富主题A中的条目和主题B。主题A是我的KStream,主题B是我的KTtable,它有大约2300万条记录。这两个主题中的键都没有计算,所以我必须使用reducer将KStream(主题B)转换为KTable。 下面是我的代码: 1)KTable初始化速度慢。(2000 msg/s左右),这正常吗?我的主题是只有1个分区。有什么方法可

  • 我阅读了kstream.leftjoin,但没有找到确切的区别。