SQL小提琴:http://sqlfiddle.com/#!3/23cf8獲取RID查找而不是表掃描?
在此查詢,當我有一個ID爲In
條款,然後還要選擇其他列中,在首先進行評估,然後將詳細列和其他列通過拉入RID查找:
--In production and in SQL Fiddle, Details is grabbed via a RID Lookup after the In clause is evaluated
SELECT [Id]
,[ForeignId]
,Details
--Generate a numbering(starting at 1)
--,Row_Number() Over(Partition By ForeignId Order By Id Desc) as ContactNumber --Desc because older posts should be numbered last
FROM SupportContacts
Where foreignId In (1,2,3,5)
使用此查詢,詳細信息正通過表掃描進入。
With NumberedContacts AS
(
SELECT [Id]
,[ForeignId]
--Generate a numbering(starting at 1)
,Row_Number() Over(Partition By ForeignId Order By Id Desc) as ContactNumber --Desc because older posts should be numbered last
FROM SupportContacts
Where ForeignId In (1,2,3,5)
)
Select nc.[Id]
,nc.[ForeignId]
,sc.[Details]
From NumberedContacts nc
Inner Join SupportContacts sc on nc.Id = sc.Id
Where nc.ContactNumber <= 2 --Only grab the last 2 contacts per ForeignId
;
在SqlFiddle,第二個查詢實際生產中得到了RID查找,而用一百萬條記錄它會產生一個表掃描(在IN
條款消除了行的99%)
否則查詢計劃在SQL小提琴顯示的是相同的,唯一的區別是,對於第二個查詢在SQL小提琴的RID查找,是表掃描在生產:(
我想明白,將導致此行爲的可能性?哪一種s的東西你會看看幫助確定它的原因在這裏使用表掃描?
我該如何影響它在那裏使用RID查找?
通過觀察在實際執行計劃經營成本,我相信我能拿到第二個查詢非常接近在性能上的第一個查詢,如果我能得到它使用一個RID查找。如果我不選擇Detail
列,那麼兩個查詢的性能在生產中都非常接近。只有在添加其他列(如Detail
)之後,第二個查詢的性能纔會顯着下降。當我把它放在SQL小提琴中,看到執行計劃使用RID查找時,我很驚訝,但有點困惑...
它沒有聚集索引,因爲在測試時使用不同的聚簇索引,這個和其他查詢的性能較差。那是在我開始添加像Details
之類的其他列之前,我可以嘗試更多,但是想要在隨機索引在黑暗中開始拍攝之前瞭解現在正在發生的事情。
也許你的意思是這個CREATE非聚集索引[IX_SupportContacts__Id] ON SupportContacts ([ID] ASC)包括:([詳情]); –
我認爲該索引,但想知道如果使索引的這樣一個大的字段部分會膨脹索引很多,並可能對該字段的插入/更新有很大的影響?不要試圖變得困難,只是對你的觀點感興趣。 – AaronLS
@AaronLS:你沒有詳細提及這些列有多大 - 而INCLUDE的美妙之處在於:這些值僅在索引的葉級別存儲**,但不包括**, *在葉級以上的索引結構中!這是一種非常高效且非常漂亮的獲得性能的方式 - 避免RID或密鑰查找可以提高性能** ** –