2013-04-22 59 views
0

我已經對索引列的順序做了一些研究,但並非100%確定,所以請耐心等待! 我有如下表:索引中列的順序 - 插入性能

CREATE TABLE [Valuation] 
    ( 
     [ValuationID] [int] IDENTITY(1, 1) 
          NOT NULL 
          CONSTRAINT [PK_Valuation] PRIMARY KEY , 
     VersionID INT NOT NULL , 
     AlphanumericIdentifier VARCHAR(255) NOT NULL, 
     ... 
     other columns 
     ... 
    ) 

我做很多連接在該表上別人上VERSIONID和AlphanumericIdentifier,所以我把一個指標就可以了:

CREATE NONCLUSTERED INDEX [IX_Valuation] ON [dbo].[Valuation] 
(
[VersionID] ASC, 
[AlphanumericIdentifier] ASC 
) 

兩個問題:

  1. 這些連接通常是針對特定的版本ID完成的,因此這是最具選擇性的列,應該是索引中的第一個 - 對嗎?
  2. 插入始終爲單個版本完成,比上一個版本多1個。這應該減少插入的性能,因爲插入的行是可以添加到索引末尾的「塊」。這是正確的嗎?

我很確定我對1,但2是正確的?

感謝 喬

+1

您是否在使用標識列來查看任何內容? VersionID + Alphenumericidentifier的組合是唯一的嗎?也許你應該考慮兩列上的PK,而不是在身份列上,如果它實際上不會被使用。 – 2013-04-22 15:42:25

+0

這聽起來像'VersionID'應該是PK(和身份證) – Lamak 2013-04-22 15:42:36

+0

VersionID + Alphenumericidentifier不是唯一的。他們**應該**與另一個varchar字段一起是唯一的,但由於涉及風險,我不能在項目的這個階段引入唯一的索引。但是,如果我可以倒退時間,聽起來像是一個好主意......另一個限制是我需要向文件中的第三方供應商發送唯一的ID。這將高達10 + 255 + 255 = 560個字符,這可能會導致他們的問題。目前我們只給他們一個int PK,只有最多10個字符就可以了 – nonpoliticaltag 2013-04-22 15:53:00

回答

0

是的,你說得對兩個。

這些列應根據您查詢的內容進行排序,其中前導列是您始終或最常見的查詢。

添加具有遞增值VersionID的行意味着不需要拆分中間頁面。

1

您的問題:

「這些連接通常是做了一個具體VERSIONID,所以這是最有選擇性的列,並應在索引中的第一」

連接與它無關,除非連接被用作過濾器。 過濾器(Where子句謂詞)和Sorting(Order By子句)使用索引。是否使用索引取決於有多少記錄(行)滿足過濾器。如果查詢將返回表中的每一行(no where子句),那麼很可能不會使用索引,因爲查詢優化器將(正確)決定只讀取整個表,而不是嘗試使用索引。索引是具有多個級別的分層樹結構。使用索引需要查詢返回的每一行的每個索引級別有一個磁盤I/O。因此,如果查詢將返回表中的所有1000行,並且索引中有五個級別,則這需要5000個IO。直接從表中讀取數據,而不是索引,只需要1000個IO。

接下來,你對「這應該減輕對刀片的性能損失爲插入的行是‘塊’,可以被添加到索引的末尾」聲明

這種說法是,如果指數只有真正的是一個聚集索引。在您的模式中,聚簇索引是主鍵(因爲雖然您可以覆蓋它,這是默認行爲),它位於ValuationID上,而不是VersionId上。因此,插入的「塊」任何記錄,它們是否都具有相同的versionId,或者不會被添加到索引的末尾,因爲它們都將具有新的valuationId s。

+0

好的,謝謝 - 對於連接是有意義的。我做了一個連接,然後在where子句中使用versionID,這樣優化器就會找出在評估時使用索引,因爲它是按照版本ID排序的,然後在它所加入的表上使用類似的索引。 – nonpoliticaltag 2013-04-22 15:59:51