Kaj*_*aja 2 sql-server optimization execution-plan sql-server-2012
我正在测试 sql server 中的合并加入。我有一个INNER JOIN
并强制优化器执行以下操作MERGE JOIN
:
ID
在个人表中是主键ID
在 Abteilung 表是主键这些表中没有其他索引
select * from [dbo].[Personal] as P inner join [dbo].[Abteilung] as A
on P.[ID]= A.[Personal_ID] OPTION (MERGE JOIN)
Run Code Online (Sandbox Code Playgroud)然后优化器使用这个计划来运行我的查询:
我想强制优化器使用index seek
而不是Table Scan
我为实现这个目标做了什么:
ID
,上定义分组索引Personal_ID
。如果我运行查询,执行计划是这样的变化:这里我有聚集索引扫描,但没有聚集索引搜索
FORCESEEK
提示。如果我使用此提示,运行查询会发生错误:由于此查询中定义的提示,查询处理器无法生成查询计划。在不指定任何提示且不使用 SET FORCEPLAN 的情况下重新提交查询。
如果我在查询中添加 where 子句,则查询将更改为:
select * from [dbo].[Personal] as P inner join [dbo].[Abteilung] as A
on P.[ID]= A.[Personal_ID] where A.[Personal_ID]=2
OPTION (MERGE JOIN)
Run Code Online (Sandbox Code Playgroud)
我的问题:
如何更改我的查询以在底线中包含聚集索引查找?
要获得聚集索引查找,您需要一个支持过滤器的聚集索引(例如,前导键必须是Personal_ID
,而不是ID
)。
如果没有前导列Personal_ID
支持过滤器的索引,则不能强制查找。
这并不意味着您应该更改现有的聚集索引,除非这是您对表运行的唯一查询。
虽然您可以创建一个Personal_ID
作为键列的非聚集索引,但是对该索引的查找可能不是您想要的 - 因为您正在使用SELECT *
(您真的确定需要两个表中的所有列吗?),它无论如何都需要从聚集索引中获取其余的列,并且如果返回的行数超过一定数量,则在某些时候进行搜索(好吧,相当于伪装为搜索的范围扫描)+ 查找将比常规扫描更昂贵。
为什么你认为你需要在这里寻找?查询返回多少行,它们有多宽,需要多长时间?这只是教育性的,还是您假设搜索总是比扫描表现更好?(它不会,顺便说一句。)
一些有用的阅读:
归档时间: |
|
查看次数: |
5421 次 |
最近记录: |