INNER JOIN与LEFT JOIN在SQL Server的性能
我创建了INNER JOIN 9桌,反正需要很长的(超过五分钟)。所以,我的民歌改变INNER JOIN来LEFT JOIN LEFT JOIN的性能较好,在首次尽管我所知道的。之后我变了,查询的速度显著提高。 我想知道为什么LEFT JOIN的速度比INNER JOIN? 我的样子如下: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
本文地址 :CodeGo.net/150174/
-------------------------------------------------------------------------------------------------------------------------
1. 一LEFT JOIN比绝对不是更快INNER JOIN。事实上,它的速度较慢,根据定义,一个外部联接(LEFT JOIN或RIGHT JOIN)所要做的所有工作INNER JOIN空扩展结果的额外工作。它也将有望重回更多的行,进一步增加了总的执行简单地归结到结果集的规模越大。 (而且,即使一LEFT JOIN是在特定的情况下更快的原因有多种难想象合流,它不是在函数上等同于INNER JOINCodeGo.net,所以你不能简单地去替换一个与其他的所有实例!) 最有可能的性能问题在其他地方,如没有一个候选键或适当的索引外键。 9表格是相当多的,能够加入这样的放缓可以从字面上几乎任何地方。如果您发布您的模式,我们也许能够提供更多的细节。 编辑: 进一步反映在此,我能想到的下一个plotLEFT JOIN可能比一个快INNER JOIN,那就是当: 的表是非常小的(例如,在10行); 该表不具有足够的索引来覆盖查询。 考虑这个例子:
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。
2. 有可能导致外部联接比内部更快地联接尚未又一个重要的场景。 外连接,优化一直是free的,从执行计划下降外连接表,如果连接列是外部表中的PK,并没有列是从外部表中选择。例如SELECT A.* FROM A LEFT OUTER JOIN B ON A.KEY=B.KEY和B.KEY是PK的B.两个甲骨文(我相信我释放10)和SQL Server(2008 R2)从执行计划trimB表。 的未必是真实的内部联接:SELECT A.* FROM A INNER JOIN B ON A.KEY=B.KEY可能会或可能不会要求乙方在执行计划根据什么constraints存在。 如果A.KEY是空的外键引用B.KEY,那么优化器不能从它必须确认A B行存在,每一个行的计划落乙。 如果A.KEY是一个强制性的外键引用B.KEY,那么优化器可以自由地从该计划的constraints保证该行的存在降乙。但是,仅仅优化器可以从该计划删除表,没有按'会的。 SQL Server 2008的R2不会从该计划跌落乙级。甲骨文10没有从计划跌落乙级。这是很容易看到的外部如何连接将在性能在这种情况下,内部联接的SQL Server上。 这是一个简单的例子,而不是实际的一个独立的查询。为什么要加入到一个表,如果你不需要? 而设计的观点时,这可能是一个非常重要的设计考虑。经常是“做一切”的观点是建立联接一切可能需要涉及到中央台。 (尤其是如果有做adhoc查询不理解关系模型)视图可以包括来自多个表中的所有相应和列。但是从视图中的表的子集的可能只访问列。如果表的连接与外连接,那么优化器可以(不)从计划落了人需要的表。 关键是要确保该外部联接给出了正确的结果。正如Aaronaught所说的-你不能一味替代OUTER JOIN的INNER JOIN和expect的结果。但是,出于性能原因的观点是何时能。 最后一个注意-我没有测试过对性能的影响,鉴于上述情况,但在理论上似乎你应该能够安全地替换INNER JOIN与OUTER JOIN,如果您还添加了状态<FOREIGN_KEY> IS NOT空的地方
3. 我所知道的几起案件,其中左连接已经比内连接速度更快。 其根本原因,我能想到的是这样的: 如果你有两个表与您携手与索引(两个表)的列。 内部联接将产生的结果不管你循环遍历上表中的一个,并配以索引表中的两个索引中的条目,如果你会做相反的:在循环中的条目索引表中的两个,并配以指数表中的一个。 问题是,当你有旧的统计数据,我查询优化索引的统计信息来找到表与至少匹配的条目(根据你的其他条件)。 如果你有两个表中的每个100万,在表中的一个有10行匹配,并在表中的两个有100000行匹配。最好的办法是做一个索引扫描的表之一,并在表中两个匹配10。相反将是一个索引扫描的遍历100000行和尝试匹配100000,只有10所以,如果统计不正确的优化器可能会选择错误的表和索引遍历。 如果优化器选择最佳的左连接在它被写入命令将执行比内连接好。 但是,优化器也可以优化左连接子优化的左半联接。为了使选择你想你FORCE ORDER提示之一。
4. 试试这两个查询(一个与内部和左连接)与OPTION (FORCE ORDER)在结束后的结果。OPTION (FORCE ORDER)是一个查询提示强制优化器与您在查询中提供的连接顺序生成执行计划。 如果INNER JOIN开始执行一样快LEFT JOIN,它是 在一个完全由INNER JOINs时,连接顺序并不重要。这给自由查询优化下令其认为合适的联接,所以该问题可能依靠优化上。 同LEFT JOIN,这是不是这样的改变连接顺序将改变查询的结果。引擎必须按照您提供的查询,这可能比优化的更好的连接顺序。 不知道这个回答你的问题,但我曾经在这特色的查询进行计算的一个项目,其中最多的优化。我们有情况下,一个FORCE ORDER将减少一个查询的执行从5分钟至10秒。
5. 您的性能问题更可能是连接你正在做的和你要加入的列是否具有索引或数量不限的。 你可以很容易地做9全表最坏的情况下会扫描每个加盟。
6. 已经做了一些左外部和内部连接和一直没能找到一个consisten之间的差异。有许多变数。我工作的一个报告数据库中有很多的表有大量的字段,在(providers版本和当地工作线程)的许多变化。这是不可能创建所有覆盖索引等多种查询的需要和处理历史数据。已经看到的内层查询kill服务器性能两个大(百万到上千万行)表是内部加入了两个拉大了许多领域,并没有覆盖索引的存在。 但最大的问题,似乎并没有在上面appeaer。也许你的数据库是精心设计与触发器和精心设计的交易处理,以确保良好的数据。矿经常有,他们没有预计NULL值。是的表定义可以执行无空值,但不是在我的选项 所以,问题是...你设计你的查询只对速度,事务处理更高优先级运行一分钟的代码。或者你去的准确性,一个左外连接将提供。该内部连接必须找到双方的,所以一个意想不到的空不仅会从两个表中删除数据,但有可能整个行和它发生这么好听,不 你可以非常快地得到90%所需要的数据,并没有发现内部连接有默默的内部连接可以更快,但我不相信任何人做这样的假设,除非他们已审阅的执行计划。速度是重要的,但是精确度更重要。
INNER JOIN与LEFT JOIN在SQL Server的性能的更多相关文章
- SQL Server 2008性能故障排查(四)——TempDB
原文:SQL Server 2008性能故障排查(四)--TempDB 接着上一章:I/O TempDB: TempDB是一个全局数据库,存储内部和用户对象还有零食表.对象.在SQLServer操作过 ...
- SQL Server 2008性能故障排查(三)——I/O
原文:SQL Server 2008性能故障排查(三)--I/O 接着上一章:CPU瓶颈 I/O瓶颈(I/O Bottlenecks): SQLServer的性能严重依赖I/O子系统.除非你的数据库完 ...
- SQL Server 2008性能故障排查(二)——CPU
原文:SQL Server 2008性能故障排查(二)--CPU 承接上一篇:SQL Server 2008性能故障排查(一)--概论 说明一下,CSDN的博客编辑非常不人性化,我在word里面都排好 ...
- 5. SQL Server数据库性能监控 - 当前请求
原文:5. SQL Server数据库性能监控 - 当前请求 对于在线运行的系统,当前数据库性能监控,通常监视以下几点: (1) 是否有阻塞 (Blocking); (2) 是否有等待 (Waitin ...
- Sql Server CPU 性能排查及优化的相关 Sql
Sql Server CPU 性能排查及优化的相关 Sql 语句,非常好的SQL语句,记录于此: --Begin Cpu 分析优化的相关 Sql --使用DMV来分析SQL Server启动以来累计使 ...
- SQL Server数据库性能优化之SQL语句篇【转】
SQL Server数据库性能优化之SQL语句篇http://www.blogjava.net/allen-zhe/archive/2010/07/23/326927.html 近期项目需要, 做了一 ...
- [转] 利用SET STATISTICS IO和SET STATISTICS TIME 优化SQL Server查询性能
首先需要说明的是这篇文章的内容并不是如何调节SQL Server查询性能的(有关这方面的内容能写一本书),而是如何在SQL Server查询性能的调节中利用SET STATISTICS IO和SET ...
- SQL SERVER 查询性能优化——分析事务与锁(五)
SQL SERVER 查询性能优化——分析事务与锁(一) SQL SERVER 查询性能优化——分析事务与锁(二) SQL SERVER 查询性能优化——分析事务与锁(三) 上接SQL SERVER ...
- SQL Server 查询性能优化 相关文章
来自: SQL Server 查询性能优化——堆表.碎片与索引(一) SQL Server 查询性能优化——堆表.碎片与索引(二) SQL Server 查询性能优化——覆盖索引(一) SQL Ser ...
- 最有效地优化 Microsoft SQL Server 的性能
为了最有效地优化 Microsoft SQL Server 的性能,您必须明确当情况不断变化时,性能将在哪些方面得到最大程度的改进,并集中分析这些方面.否则,在这些问题上您可能花费大量的时间和精力 ...
随机推荐
- 让IE浏览器支持CSS3表现
http://www.zhangxinxu.com/wordpress/2010/04/%e8%ae%a9ie6ie7ie8%e6%b5%8f%e8%a7%88%e5%99%a8%e6%94%af%e ...
- jq闭包
var jy = jQuery.noConflict(); (function($){ //里面跟jq的所有代码 })(jy)
- 动态调用WebService方法
好像很多人做WebService的时候都是直接添加引用的方式,然后调用服务端的方法.这样就个问题,就是每次我服务端添加了方法或者修改了方法后都要更新Web引用,这样比较麻烦.下面给一个不用添加引用 ...
- .net VS2008 时间加减,时间段,时间格式化到秒
举个例子: DateTime time1 = DateTime.Now; DateTime time2 = time1.AddDays(1); time1是当前时间,time2比当前时间多一天.也就是 ...
- iOS 多页面跳转同一页面时数据处理
如果 同一个界面, 会有10个数据源传进来, 此时 创建 一个总模型fullmodel 存储 10个model 数据, 创建 10个一样的cell, 在 不同数据, 用不同cell处理最好, 千万别于 ...
- java代码分析及分析工具
一个项目从搭建开始,开发的初期往往思路比较清晰,代码也比较清晰.随着时间的推移,业务越来越复杂.代码也就面临着耦合,冗余,甚至杂乱,到最后谁都不敢碰. 作为一个互联网电子商务网站的业务支撑系统,业务复 ...
- ServiceStack支持跨域提交
//ServiceStack对浏览器有一定的限制 //修改AppHost.cs文件 using Funq;using ServiceStack;using ServiceStackTest.Servi ...
- BZOJ3170: [Tjoi2013]松鼠聚会 - 暴力
描述 有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最短距离. 题解 简直 ...
- 使用phpExcel导出excel文件
function export($log_list_export) { require "../include/phpexcel/PHPExcel.php"; require &q ...
- Memocache
http://blog.csdn.net/zhoufoxcn/article/details/6282099 http://blog.csdn.net/dinglang_2009/article/de ...