我创建了在9个表上使用INNER JOIN的SQL命令,无论如何,此命令将花费很长时间(超过五分钟)。所以我的同事建议我将INNER JOIN更改为LEFT
JOIN,因为尽管我知道,但LEFT JOIN的性能更好。更改后,查询速度得到了显着提高。
我想知道为什么LEFT JOIN比INNER JOIN快?
我的SQL命令看起来象下面这样: SELECT * FROM A INNER JOIN B ON ... INNER JOIN C ON ... INNER JOIN D
等
更新: 这是我的架构的简要介绍。
FROM sidisaleshdrmly a -- NOT HAVE PK AND FK
INNER JOIN sidisalesdetmly b -- THIS TABLE ALSO HAVE NO PK AND FK
ON a.CompanyCd = b.CompanyCd
AND a.SPRNo = b.SPRNo
AND a.SuffixNo = b.SuffixNo
AND a.dnno = b.dnno
INNER JOIN exFSlipDet h -- PK = CompanyCd, FSlipNo, FSlipSuffix, FSlipLine
ON a.CompanyCd = h.CompanyCd
AND a.sprno = h.AcctSPRNo
INNER JOIN exFSlipHdr c -- PK = CompanyCd, FSlipNo, FSlipSuffix
ON c.CompanyCd = h.CompanyCd
AND c.FSlipNo = h.FSlipNo
AND c.FSlipSuffix = h.FSlipSuffix
INNER JOIN coMappingExpParty d -- NO PK AND FK
ON c.CompanyCd = d.CompanyCd
AND c.CountryCd = d.CountryCd
INNER JOIN coProduct e -- PK = CompanyCd, ProductSalesCd
ON b.CompanyCd = e.CompanyCd
AND b.ProductSalesCd = e.ProductSalesCd
LEFT JOIN coUOM i -- PK = UOMId
ON h.UOMId = i.UOMId
INNER JOIN coProductOldInformation j -- PK = CompanyCd, BFStatus, SpecCd
ON a.CompanyCd = j.CompanyCd
AND b.BFStatus = j.BFStatus
AND b.ProductSalesCd = j.ProductSalesCd
INNER JOIN coProductGroup1 g1 -- PK = CompanyCd, ProductCategoryCd, UsedDepartment, ProductGroup1Cd
ON e.ProductGroup1Cd = g1.ProductGroup1Cd
INNER JOIN coProductGroup2 g2 -- PK = CompanyCd, ProductCategoryCd, UsedDepartment, ProductGroup2Cd
ON e.ProductGroup1Cd = g2.ProductGroup1Cd
ALEFT JOIN
绝对不会比A快INNER JOIN
。实际上,它比较慢。根据定义,外部联接(LEFT JOIN
或RIGHT JOIN
)必须完成所有工作INNER JOIN
以及对结果进行null扩展的额外工作。仅仅由于结果集的大小,也期望返回更多的行,从而进一步增加了总的执行时间。
(而且即使LEFT JOIN
是 在更快的 特定 情况下,由于一些难以想象的因素汇合,它不是功能上等同于INNER JOIN
,所以你不能简单地去更换一个与其他的所有实例!)
您的性能问题很可能位于其他地方,例如没有正确索引候选键或外键。9个表有很多要加入的地方,因此减速几乎可以在任何地方进行。如果您发布架构,我们也许可以提供更多详细信息。
编辑:
进一步思考这一点,我可以想到一种情况,在这种情况下,aLEFT JOIN
可能比快INNER JOIN
,而在这种情况下:
考虑以下示例:
CREATE TABLE #Test1
(
ID int NOT NULL PRIMARY KEY,
Name varchar(50) NOT NULL
)
INSERT #Test1 (ID, Name) VALUES (1, 'One')
INSERT #Test1 (ID, Name) VALUES (2, 'Two')
INSERT #Test1 (ID, Name) VALUES (3, 'Three')
INSERT #Test1 (ID, Name) VALUES (4, 'Four')
INSERT #Test1 (ID, Name) VALUES (5, 'Five')
CREATE TABLE #Test2
(
ID int NOT NULL PRIMARY KEY,
Name varchar(50) NOT NULL
)
INSERT #Test2 (ID, Name) VALUES (1, 'One')
INSERT #Test2 (ID, Name) VALUES (2, 'Two')
INSERT #Test2 (ID, Name) VALUES (3, 'Three')
INSERT #Test2 (ID, Name) VALUES (4, 'Four')
INSERT #Test2 (ID, Name) VALUES (5, 'Five')
SELECT *
FROM #Test1 t1
INNER JOIN #Test2 t2
ON t2.Name = t1.Name
SELECT *
FROM #Test1 t1
LEFT JOIN #Test2 t2
ON t2.Name = t1.Name
DROP TABLE #Test1
DROP TABLE #Test2
如果运行此命令并查看执行计划,则会发现INNER JOIN
查询确实比花费更多LEFT JOIN
,因为它满足了上述两个条件。这是因为SQL
Server希望对进行散列匹配INNER JOIN
,但对进行嵌套循环LEFT JOIN
。前者 通常 要快得多,但是由于行数非常小 并且
没有索引可使用,因此哈希运算被证明是查询中最昂贵的部分。
通过使用自己喜欢的编程语言编写程序,在具有5个元素的列表(与具有5个元素的哈希表)上执行大量查找,您可以看到相同的效果。由于大小,散列表的版本实际上要慢一些。但是将其增加到50个元素或5000个元素,并且列表版本的速度变慢,因为哈希表的O(N)对O(1)。
但是将此查询更改为ID
列而不是列Name
,您将看到一个截然不同的故事。在这种情况下,它为两个查询嵌套循环,但INNER JOIN
版本能够取代聚簇索引扫描的一个与寻求-这意味着这简直就 一个数量级 有大量行的速度更快。
因此,结论或多或少是我上面提到的几段内容。这几乎可以肯定是一个索引或索引覆盖问题,可能与一个或多个非常小的表结合在一起。在这些情况下,SQL
Server有时 可能 为而INNER JOIN
不是选择更糟糕的执行计划LEFT JOIN
。
问题内容: 我想以以下方式实现sql查询: 我该如何使用或上面提到的方法来做到这一点? 问题答案: 是一个方法从查询类。 您可以尝试这样的事情。
我有一个2.1.4版本的项目,带有spring boot数据。 该项目具有以下关系实体:ApplicationEntity ApplicationTranslateEntity LanguageEntity它在数据库中有一个区域设置关系表(ManyToMany),该表中有一个用于不同语言的文本的额外表(ApplicationTranslateEntity)。 org.hibernate.Query
问题内容: 我正在尝试在SQLServer中聚合“ STRING”字段。我想找到与Oracle中相同的函数LISTAGG。 您知道如何执行相同的功能或其他方法吗? 例如, 我希望这个查询的结果是 问题答案: 从SQL Server 2017开始,该功能可用,从而大大简化了逻辑: 在SQL Server中,您可以用来获取结果:
我阅读了kstream.leftjoin,但没有找到确切的区别。
本文向大家介绍SQLServer地址搜索性能优化,包括了SQLServer地址搜索性能优化的使用技巧和注意事项,需要的朋友参考一下 这是一个很久以前的例子,现在在整理资料时无意发现,就拿出来再改写分享。 1.需求 1.1 基本需求: 根据输入的地址关键字,搜索出完整的地址路径,耗时要控制在几十毫秒内。 1.2 数据库地址表结构和数据: 表TBAddress 表数据 1.3 例子:
问题内容: 这个问题已经在这里有了答案 : SQL中的TRUNCATE和DELETE有什么区别 (32个答案) TRUNCATE vs DELETE FROM的利弊 (11个答案) 6年前关闭。 关于mysql / sqlserver,我的脑海里发生了一件事,即 删除/截断 哪个更好更快? 在哪里使用删除? 在哪里使用截断? 问题答案: 删除 DELETE是DML命令。 使用行锁执行DELETE语
node-sqlserver 是微软官方发布的 SQL Server 的 Node.js 的驱动程序。可允许 Windows 上运行的 Node.js 程序访问 SQL Server 和 Windows Azure SQL 数据库。 该项目托管在 Github 上。
sqlserver manager 是一个多功能sqlserver图形管理界面,支持自定义导入导出,自动扫描服务器,数据库。