強制 Sql 伺服器在合併連接中使用索引查找
我正在測試 sql server 中的 Merge join。我有一個
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)
然後優化器使用這個計劃來執行我的查詢:
我想強制優化器使用
index seek
而不是Table Scan
我為實現這一目標所做的工作:
- 在表 Abteilung 中定義分組索引的列
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)
我的問題:
如何更改我的查詢以使聚集索引搜尋在底線?
要獲得聚集索引搜尋,您需要一個支持過濾器的聚集索引(例如,前導鍵必須是
Personal_ID
,而不是ID
)。
Personal_ID
如果沒有支持過濾器的前導列的索引,則不能強制搜尋。這並不意味著您應該更改現有的聚集索引,除非這是您曾經對該表執行的唯一查詢。
雖然您可以創建一個以作為鍵列的非聚集索引,
Personal_ID
但對該索引的查找可能不是您想要的 - 因為您正在使用SELECT *
(您真的確定需要兩個表中的所有列嗎?),它無論如何都需要從聚集索引中獲取其餘列,如果返回的行數超過一定數量,則在某個時候進行搜尋(好吧,相當於偽裝成搜尋的範圍掃描)+查找將比正常掃描更昂貴。為什麼你認為你需要在這裡尋找?查詢返回多少行,它們有多寬,需要多長時間?這只是教育性的,還是您假設搜尋總是比掃描更好?(它不會,順便說一句。)
一些有用的閱讀:
在沒有創建任何測試的情況下,我猜想在沒有搜尋謂詞的情況下搜尋索引是不可能的,特別是如果您使用 SELECT * 並獲取所有表列。
我會嘗試過濾作為您要查找的索引的一部分的索引列,並僅檢索該索引所涵蓋的列。
文件解釋說,合併連接通常會在之後對其進行掃描或排序。閱讀:https ://technet.microsoft.com/en-us/library/ms190967(v=sql.105).aspx