SQL Server 2012是否延迟加入
我正在开发一个应用程序,允许用户动态选择他们看到的内容。这些列和表所属的列表非常庞大。我正在构建一个动态查询,但如果没有,我不想存储所有的连接逻辑。 例如,我有一个查询,它为10个表留下了连接,但我只按一个表进行选择和筛选。SQL Server 2012是否足够智能,可以不连接其他不需要的表 我知道Oracle的DBMS是这样工作的,但我的公司使用的是SQL Server 2012,所以我坚持使用它 不需要执行最后4个左联接的查询示例: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
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将知道联接不能负责向结果集添加更多行。