2012-11-21 42 views
0

我對SQLServer相當陌生,有一件事情讓我很困擾。希望你們中的一個能向我解釋發生了什麼事。爲什麼在弱實體中需要單獨的索引?

當我在一個索引過程跑活動監視器,我意識到,某些查詢,包括弱實體花費的時間比預期的 - 甚至是陌生人 - SQLServer的建議在形式的弱實體創建一個索引

CREATE NONCLUSTERED INDEX [<INDEXNAME>] 
ON [dbo].[<TABLE>] ([<ID1>]) 
INCLUDE ([<ID2>]) 
GO 

這樣做(實際上我對兩列建立了索引,但我認爲結果幾乎相同)確實提高了查詢速度(至少從我在活動監視器中看到的情況)。

CREATE UNIQUE NONCLUSTERED INDEX [<INDEXNAME>] ON [dbo].[<TABLE>] 
(
    [<ID1>] ASC, 
    [<ID2>] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 

我現在的問題是:SQLServer是否忽略聚集索引?如果是,爲什麼?我能以某種方式解決這個問題嗎對我來說,添加另一個實際上應該與主鍵索引具有完全相同內容的索引似乎很奇怪。

+0

什麼是弱實體?它與NHibernate有什麼關係? –

+1

由於既沒有顯示查詢也沒有顯示聚集索引,因此很難弄清楚它是否可能被忽略以及爲什麼。也許這些列的順序不同?您還應該使用MS SQL Server Management Studio的「顯示執行計劃」功能來探索查詢的執行方式。 –

回答

2

可能有多種原因 - 向我們展示您的聚集索引的定義以澄清。

如果您的聚簇索引位於ID2和ID1上,並且您在查詢中選擇了兩個列,但在where子句中使用了ID1,那麼這個新的非聚簇索引運行起來會更快。

如果您只有1列上的非聚簇索引但選擇了兩列,那麼它必須去聚簇索引查找數據,因此在這種情況下將第二列添加爲INCLUDEd列或甚至是第二索引列避免SQL服務器必須觸摸數據頁面。

如果在另一方面你的聚集索引以相同的順序,可以是任何的:

  1. 填充因子的聚集索引 - 如果填充因數低,數據通過攤開更多的數據頁面比需要的更多,它可能比從人口密度更高的非聚集索引中讀取要慢
  2. 聚簇索引所在的文件組(最終磁盤) - 如果不同,查詢優化程序可能會識別高爭用或聚集索引磁盤上的搜尋速度較慢
  3. 您一直在插入順序數據到聚簇索引中並且聚簇索引b樹現在成爲頂點
  4. 表中出現了許多插入操作,導致很多頁分割,導致聚簇索引中的數據未按物理順序排列
  5. 您的集羣索引不是唯一的 - 在這種情況下,SQL服務器將爲您的聚簇索引添加一個唯一值,使其更大,因此需要讀取更多數據,因此速度比等效非聚簇索引要慢。您的聚簇索引僅處於開啓狀態1列(見下面)

如果你有你的聚簇索引1列(例如ID1),索引數據是2個邏輯讀入索引,但是ID2列數據位於索引的葉片上,其深度爲3個讀取。

對於等效的非聚集索引,它只需要2個邏輯讀取,因爲它不必訪問數據頁面,這意味着非聚集索引的速度會快1/3。

退房如何聚集索引和非聚集索引存儲:

Clustered Index Structures

Non-Clustered Index Structures

讓我知道它是!

+0

嗨戴夫,謝謝你的回答,我想這對我來說有點太深。 :)我想這一切都歸結爲如何以最佳方式對這些表進行索引的問題,假設只有非常罕見的寫操作,並且我可以隨時重新索引。我最初的假設是擁有主鍵就足夠了,顯然情況並非如此。我的下一個假設是添加一個'反向'索引,這意味着如果聚集索引是[A],[B]添加索引[B],包括[A]。那麼我是否應該添加[A],包括[B]?我的假設是完全錯誤的嗎? – Markus

+0

如果您可以隨時重新編制索引並進行罕見寫入並希望進行最佳讀取,則爲每個查詢類型創建一個覆蓋非聚簇索引。 例如如果您的查詢是從tableX中選擇A,B,C,其中A =?然後在A上創建一個索引,並且包括另外兩個columsn B和C以使其成爲覆蓋索引。 –

+1

要回答您的問題,您的假設只是在黑暗中猜測 - 您在此案例中的索引選擇將基於您擁有的查詢類型。這裏是另一個例子 - 從tableX中選擇A,B,C,D,其中A =?和C =? ORDER BY D DESC。爲此:tableX(A,C,D DESC)INCLUDE(B)上的CREATE INDEX ix1 - 注意:在這種情況下,您可以交換A和C並獲得相似的結果 - 這取決於這些列的選擇性。 –

相關問題