天天看點

第十章——維護索引(8)——在計算列中建立索引提高性能前言:準備工作:步驟:分析:

在了解計算列上的索引之前,先了解計算列的基本知識。計算列由可以使用同一表中的其他列的表達式計算得來。表達式可以是非計算列的列名、常量、函數,也可以是用一個或多個運算符連接配接的上述元素的任意組合。表達式不能為子查詢。

預設情況下,計算列是一個虛拟的列,并且可以在調用時重新計算,直到在CREATE TABLE或者ALTER TABLE 指令中使用PERSISTED。

如果列定義成PERSISTED,會存放計算值,并存放在原始列上更新後的彙總值,不能對計算列進行INSERT、UPDATE。

首先要了解是否有需要在計算列上建立索引,計算列在下面情況可以考慮建立索引:

1、 如果計算列的資料來源于IMAGE,TEXT和NTEXT資料類型,隻能作為非聚集索引的部分列。

2、 計算清單達式不能是REAL或者FLOAT資料類型。

3、 計算列必須明确。

4、 計算列必須具有穩定性。可以使用COLUMNPROPERTY函數的IsDeterministic屬性來判斷是否穩定。

5、 如果函數使用了任何函數,不管是自定義還是系統内置的,那麼表和函數的擁有者必須是相同的。

6、 不能用于通過聚集函數獲得的函數值上的列。

7、 需要開啟下面的配置:

1、 ARITHABORT

2、 CONCAT_NULL_YIELDS_NULL

3、 QUOTED_IDENTIFIER

4、 ANSI_WARNINGS

5、 ANSI_NULLS

6、 ANSI_PADDING

7、 NUMERIC_ROUNDABORT——OFF,其他為ON 。

1、 建立一個測試表:

2、 現在建立一個用于計算列的自定義函數,并添加計算列NetPrice到新表中,這個列通過自定義函數UDFTotalAmount來計算值:

3、 現在在表上建立一個聚集索引。使得表不會再是堆表,然後按照前面說的,修改相關的SET選項,然後開啟STATISTICS,記住目前沒有建立任何索引在計算列上: 

得到結果:

SQL Server 分析和編譯時間:

   CPU 時間= 920 毫秒,占用時間= 967 毫秒。

   CPU 時間= 0 毫秒,占用時間= 5 毫秒。

(3864 行受影響)

表'salesorderdetaildemo'。掃描計數1,邏輯讀取757 次,實體讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 實體讀取0 次,lob 預讀0 次。

 SQL Server 執行時間:

   CPU 時間= 780 毫秒,占用時間= 1643 毫秒。

4、 在建立索引到計算列前,先檢查是否符合建立條件:

5、 現在在計算列上建立索引,如果你前面說的條件都滿足,那麼可以建立了:

然後再次執行查詢:

6、 結果如下:

 SQL Server 分析和編譯時間:

   CPU 時間= 0 毫秒,占用時間= 0 毫秒。

   CPU 時間= 0 毫秒,占用時間= 3 毫秒。

   CPU 時間= 780 毫秒,占用時間= 1534 毫秒。

        在計算列建立一個索引,存儲鍵值到葉子節點并在SELECT的時候利用索引的統計資訊,在大部分的情況下是工作得很好的。但是也有很多情況下不能用計算列。

        在統計資料上,可以看到SQLServer Parse和Compile 時間還有SQLServer執行時間。如果資料量很大,那麼建立了索引在計算列上的效能提高将會很明顯。