2012-09-25 144 views
2

所以,我們有一個表,InventoryListItems,有幾列。因爲我們要尋找以基於particlar柱(g_list_id,外鍵)乘以行,我們有一個外鍵列置於我們會打電話給MYINDEX一個非聚集索引。爲什麼在索引列時收到聚集索引掃描?

所以,當我搜索數據是這樣的:

-- fake data for example 
DECLARE @ListId uniqueidentifier 
SELECT @ListId = '7BCD0E9F-28D9-4F40-BD67-803005179B04' 

SELECT * 
FROM [dbo].[InventoryListItems] 
WHERE [g_list_id] = @ListId 

我預計它將使用MYINDEX索引找到剛纔所需要的行,然後查找在這些行的信息。所以不如在索引本身中找到我們需要的所有東西,但仍然是對錶格進行全面掃描的巨大勝利。

但相反,它似乎我仍然得到一個聚集索引掃描。我無法弄清楚爲什麼會發生。

如果我做了什麼樣的指數包含的列只選擇了值,但它確實是我所期望的,一個索引查找,只是拉一切從指數。

但是,如果我SELECT *,爲什麼它只是保留在索引上,並進行掃描,似乎它仍然會因使用它而受益匪淺,因爲它在WHERE子句中被引用?

+0

這些鏈接將幫助回答您的問題:[Link1](http://stackoverflow.com/questions/6289393/why-would-sql-server-choose-clustered-index-scan-over-non-clustered-one )[鏈路2](http://sqlblog.com/blogs/kalen_delaney/archive/2007/07/22/did-you-know-forcing-a-nonclustered-index-scan-to-avoid-sorting.aspx) Link3](http://www.sqlskills.com/BLOGS/KIMBERLY/post/The-Tipping-Point-Query-Answers.aspx)希望這會有所幫助。 – Luftwaffe

回答

2

既然你做了SELECT *,因此您檢索所有列,SQL Server的查詢優化器可能已經決定它更容易和更高效的只是做一個聚集索引掃描 - 因爲它需要去聚集索引的葉無論如何要獲取所有列(首先進行查找,然後進行關鍵查找以真正獲取整個數據頁面,這是相當昂貴的操作 - 在此設置中掃描可能會更有效)。

我幾乎可以肯定,如果你嘗試

SELECT g_list_id 
FROM [dbo].[InventoryListItems] 
WHERE [g_list_id] = @ListId 

話,會有一個索引尋求,而不是(因爲你只是檢索一列 - 不是一切)。

這就是爲什麼我會建議要格外小心使用SELECT * ....時的原因之一 - 嘗試,如果以往任何時候都可能避免它。

+1

理論上,它應該進行尋找和關鍵查找,但這一切都取決於表的寬度,g_list_id是主鍵還是唯一的,並且可能還有其他一些我沒有足夠清醒的因素。 –

+0

@AaronBertrand:如果'g_list_id'只返回一行(或**非常少的**) - 但是如果這匹配了10,20,50行....那麼做所有這些關鍵的查找將是正確的太貴了 - 對嗎? –

+0

@marc_s是的,的確如此。我在倒數第二段強調......但我想我不明白爲什麼。如果表中有一百萬行,並且我們選擇了1,那麼這是否仍然會發生,或者這是優化器可能會選擇的東西,並決定另一種方式? – Beska

相關問題