我有一个包含许多连接的大型查询,我正在尝试调整,并且一个警告标志是在整个过程中使用了很多很多哈希连接。我去了查询树的底部,然后去了那里的第一个连接,这是一个内连接。
表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)
以下查询将返回合并连接,如前所述:
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;
如您所见,查询正在使用上述两个索引。另一方面,相同的连接发生在更大的查询中,下图显示了计划的一角,此连接作为散列连接发生:
我可以看到的一个区别是,哪个表格是&#34;内部&#34;表格vs&#34;外部&#34;表。但是,如果两个查询都是同一列上的内部联接,为什么这会影响执行计划?
答案 0 :(得分:0)
SQL Server查询优化器不保证最佳查询。它在设置自己的时间内寻找最佳查询。随着查询变得越来越大,通过多个连接,不同组合的数量呈指数级增长,无法探索每条可能的路径,从而保证最佳解决方案。
通常,如果您的表格设计合理(具有适当的索引)并且统计信息是最新的,您应该能够信任查询优化器。
不同的连接选择可能是由于可用的资源不同 - (CPU和内存),考虑到并行执行计划的其他部分。
如果你想进一步调查,我会测试运行连接提示,以确定执行计划是否做出了最佳决策。使用查询提示MAXDOP = 1也可能值得测试,以确定并行执行是否会影响优化器做出的选择。