Rob*_*man 5 sql-server hash merge
我有一个很大的查询,其中包含许多我正在尝试调整的连接,一个警告信号是整个过程中使用了很多很多散列连接。我转到查询树的底部,然后转到那里的第一个连接,这是一个内部连接。
表 A 使用聚集索引扫描来检索其数据,该数据按连接列排序。表 B 使用非聚集索引扫描,它也在连接列上排序。
当我单独连接这两个表并选择相同的列集时,优化器使用合并连接。被连接的集合大小大致相同,并且不是很大(<5,000 行)。
在这种情况下,什么可以解释优化器选择散列连接而不是合并连接?
编辑
根据要求,我添加了更多细节。索引定义是:
CREATE NONCLUSTERED INDEX NCL_Asset_Issuer_MergeInduce ON Asset.IssuerCompanyId (CompanyId)INCLUDE (IsPrivate,HasPublicEquity,Ticker,FinancialTemplateID,BondTicker,SICOther1ID,SICOther4ID,SICSandPID,SICOther3ID,SICMoodyID,CurrencyTypeID,SecondaryAnalystID,AnalystID,SICOshaID,SecondaryBondTicker,FiscalYearEnd,EquityExchangeID);
CREATE NONCLUSTERED INDEX NCL_Asset_IssuerCustom_IssuerId ON Asset.IssuerCustom (IssuerID) INCLUDE (Text3,ListItem1ID,ListItem5ID,ListItem3ID,ListItem2ID,Version,text4,TextLong15,ListItem6ID)
Run Code Online (Sandbox Code Playgroud)
正如我之前提到的,以下查询将返回一个合并连接:
SELECT IsPrivate,HasPublicEquity,Ticker,FinancialTemplateID,BondTicker,SICOther1ID,SICOther4ID,SICSandPID,SICOther3ID,SICMoodyID,CurrencyTypeID,SecondaryAnalystID,AnalystID,SICOshaID,SecondaryBondTicker,FiscalYearEnd,EquityExchangeID,ic.ListItem2Id,ic.ListItem3ID,ic.IssuerId
FROM Asset.Issuer i
INNER JOIN Asset.IssuerCustom ic ON i.CompanyId = ic.IssuerId;
Run Code Online (Sandbox Code Playgroud)

如您所见,查询同时使用了上述两个索引。另一方面,这个相同的连接发生在一个更大的查询中,下图显示了计划的角落,这个连接作为散列连接发生:

我可以看到的一个区别是,在哪个表是“内部”表与哪个表是“外部”表方面存在逆转。尽管如此,如果两个查询都是同一列上的内部联接,为什么这会影响执行计划?
小智 0
SQL Server 查询优化器不保证最佳查询。它会在自己设定的时间内寻找最佳查询。随着查询变得很大,并且具有多个联接,不同组合的数量呈指数级增长,并且不可能探索每条可能的路径并因此保证最佳解决方案。
通常,如果您的表设计合理(具有适当的索引)并且统计信息是最新的,您应该能够相信查询优化器能够出色地完成工作。
考虑到并行执行的计划的其他部分,连接的不同选择可能是由于可用资源不同(CPU 和内存)。
如果您想进一步调查,我将使用连接提示来测试运行,以了解执行计划是否做出了最佳决策。还可能值得使用查询提示 MAXDOP=1 进行测试,以查明并行执行是否会影响优化器所做的选择。
| 归档时间: |
|
| 查看次数: |
1600 次 |
| 最近记录: |