SQL Server 2012是否延迟加入

SQL Server 2012是否延迟加入,sql,sql-server-2012,left-join,database,Sql,Sql Server 2012,Left Join,Database,我正在开发一个应用程序,允许用户动态选择他们看到的内容。这些列和表所属的列表非常庞大。我正在构建一个动态查询,但如果没有,我不想存储所有的连接逻辑。 例如,我有一个查询,它为10个表留下了连接,但我只按一个表进行选择和筛选。SQL Server 2012是否足够智能,可以不连接其他不需要的表 我知道Oracle的DBMS是这样工作的,但我的公司使用的是SQL Server 2012,所以我坚持使用它 不需要执行最后4个左联接的查询示例: SELECT [IncidentIncidentNumbe

我正在开发一个应用程序,允许用户动态选择他们看到的内容。这些列和表所属的列表非常庞大。我正在构建一个动态查询,但如果没有,我不想存储所有的连接逻辑。 例如,我有一个查询,它为10个表留下了连接,但我只按一个表进行选择和筛选。SQL Server 2012是否足够智能,可以不连接其他不需要的表

我知道Oracle的DBMS是这样工作的,但我的公司使用的是SQL Server 2012,所以我坚持使用它

不需要执行最后4个左联接的查询示例:

SELECT [IncidentIncidentNumberModValue].[IncidentNumber]
    ,IncidentNumberModifierNotValue.[Value] AS IncidentNumberNotValue
    ,[Incident].[IncidentDate]
    ,[Incident].[ResponseNumber]
    ,[Incident].[PatientCareReportNumber]
    ,[IncidentType].[Value] AS IncidentType
    ,[SceneStreetAddressModValue].[StreetAddress2] AS IncidentAddress
    ,IncidentStreetAddressNotValue.[Value] AS IncidentAddressNotValue
    ,COUNT(*) OVER() AS TotalRecordCount
FROM [EmsEvent].[Incident]
    LEFT JOIN [Resource].[IncidentType] ON [EmsEvent].[Incident].[IncidentType] = [Resource].[IncidentType].[IncidentTypeID]
    LEFT JOIN [EmsEvent].[IncidentIncidentNumberModValue] ON [EmsEvent].[Incident].[IncidentID] = [EmsEvent].[IncidentIncidentNumberModValue].[IncidentID]
    LEFT JOIN [GlobalResource].[IncidentNumberModifier] ON [EmsEvent].[IncidentIncidentNumberModValue].[NotValue] = [GlobalResource].[IncidentNumberModifier].[DataElementID]
    LEFT JOIN [GlobalResource].[NotValue] IncidentNumberModifierNotValue ON [GlobalResource].[IncidentNumberModifier].[NotValueID] = IncidentNumberModifierNotValue.[NotValueID]
    LEFT JOIN [EmsEvent].[Scene] ON [EmsEvent].[Scene].[IncidentID] = [EmsEvent].[Incident].[IncidentID]
    LEFT JOIN [EmsEvent].[SceneStreetAddressModValue] ON [EmsEvent].[Scene].[SceneID] = [EmsEvent].[SceneStreetAddressModValue].[SceneID]
    LEFT JOIN [GlobalResource].[IncidentStreetAddressModifier] ON [EmsEvent].[SceneStreetAddressModValue].[NotValue] = [GlobalResource].[IncidentStreetAddressModifier].[DataElementID]
    LEFT JOIN [GlobalResource].[NotValue] IncidentStreetAddressNotValue ON [GlobalResource].[IncidentStreetAddressModifier].[NotValueID] = IncidentStreetAddressNotValue.[NotValueID]
    LEFT JOIN [EmsEvent].[CustomConfig] on [EmsEvent].[Incident].[IncidentID] = [EmsEvent].[CustomConfig].[IncidentID]
    LEFT JOIN [EmsEvent].[IncidentDisasterType] on [EmsEvent].[Incident].[IncidentID] = [EmsEvent].[IncidentDisasterType].[IncidentID]
    LEFT JOIN [EmsEvent].[Response] on [EmsEvent].[Scene].[SceneID] = [EmsEvent].[Response].[SceneID]
    LEFT JOIN [EmsEvent].[CrewMember] on [EmsEvent].[Response].[ResponseID] = [EmsEvent].[CrewMember].[ResponseInformationID]

WHERE [EmsEvent].[Incident].[DeletedStatus] = 0
    AND [EmsEvent].[Incident].AgencyID = '607CEE05-276D-49A1-B6BF-FD606EFC2377'
ORDER BY [EmsEvent].[IncidentIncidentNumberModValue].[IncidentNumber] ASC
OFFSET 0 ROWS
FETCH NEXT 25 ROWS ONLY
OPTION(recompile)

这取决于在联接中使用的左侧外部联接表中的哪一列

如果该列是主键或具有唯一约束,则如果在查询的其他位置未引用该表,则该表将从查询计划中排除

看起来您的最后四个表并不是在各自的主键上联接的

对于这样的表格:

create table Parent
(
  ParentID int primary key
)

create table Child
(
  ChildID int primary key,
  ParentID int references Parent(ParentID)
)
此查询将不使用表
父项

select C.*
from Child as C
  left outer join Parent as P
    on P.ParentID = C.ParentID

但是这个查询必须使用左外联接子表,因为如果外键被多次命中,它可能会向结果中添加行

select P.*
from Parent as P
  left outer join Child as C
    on P.ParentID = C.ParentID

使用
选项(重新编译)
将告诉优化器在每次执行查询时创建新的查询计划。如果有不需要的
联接
,它们将被排除。确保在“未使用的”联接表上没有筛选器。嗯,当我将其添加到查询的末尾时,执行计划仍然显示已联接的不需要的表。有什么诀窍可以让它以我所需要的方式工作吗?我用有问题的查询更新了原始帖子。我明白了,因为我正在用外键连接这些表,SQL无论如何都会尝试连接它们。@Ranger1230是的,至少在我的答案中有一个简单的例子。然后SQL Server将知道联接不能负责向结果集添加更多行。