資料類型:rowversion,不適合做為索引鍵 (尤其是主索引鍵) 的候選項。
可以在資料類型:rowversion上建立索引,但在異動時會產生更大磁碟 IO 負載。
說明
每次修改或插入含 rowversion 資料行的資料列時,都會在 rowversion 資料行中插入累加的資料庫資料列版本值。
這個屬性會使 rowversion 資料行不適合做為索引鍵 (尤其是主索引鍵) 的候選項。
資料列的任何更新都會變更資料列版本值,因而會變更索引鍵值。
如果資料行在主索引鍵中,舊的索引鍵值便不再有效,參考舊值的外部索引鍵也不再有效。
如果動態資料指標參考資料表,所有更新都會變更資料列在資料指標中的位置。
如果資料行在索引鍵中,資料列的所有更新也會產生索引的更新。
-- P01_檢視資料表的索引類型
-- P02_快速_檢視指定資料庫內的每一個索引之片段(fragmentation)資訊,使用 SAMPLED 模式
大量的I/D/U後,觀察:
-- P03_快速_檢視指定資料庫內的每一個索引之片段(fragmentation)資訊,使用 SAMPLED 模式
-- P04_觀察:rowversion資料行,有建立索引的使用特性 -- Index Seek
-- P05_觀察:rowversion資料行,沒有建立索引的使用特性 - Clustered index Scan
範例程式碼
-- 01_建立範例資料表:rowversion_Index1 與 rowversion_NoIndex1 USE DBRV01 GO CREATE TABLE rowversion_Index1 (sid int IDENTITY PRIMARY KEY, pid varchar(50), rowrev rowversion) GO CREATE TABLE rowversion_NoIndex1 (sid int IDENTITY PRIMARY KEY, pid varchar(50), rowrev rowversion) GO -- 02_在範例資料表:rowversion_Index1 的 rowversion資料行上,建立索引 CREATE NONCLUSTERED INDEX [NCL01_rowversion] ON [dbo].[rowversion_Index1] ( [rowrev] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) GO --03 檢視資料表的索引類型 SELECT t.name N'資料表', i.name N'索引名稱', i.type_desc N'索引類型的描述', i.is_unique N'索引是否唯一' FROM sys.tables t INNER JOIN sys.indexes i ON t.object_id = i.object_id GO -- 04_快速_檢視指定資料庫內的每一個索引之片段(fragmentation)資訊,使用 SAMPLED 模式 SELECT sch.name N'結構描述', obj.name N'資料表', inx.name AS N'索引名稱', index_type_desc N'索引類型', avg_fragmentation_in_percent '片段(%)', avg_page_space_used_in_percent N'頁面飽和度(%)', fragment_count, avg_fragment_size_in_pages, page_count FROM sys.dm_db_index_physical_stats (DB_ID(), NULL,NULL, NULL, 'SAMPLED') AS phy INNER JOIN sys.indexes AS inx ON phy.object_id = inx.object_id AND phy.index_id = inx.index_id INNER JOIN sys.objects AS obj ON phy.object_id = obj.object_id INNER JOIN sys.schemas AS sch ON obj.schema_id = sch.schema_id WHERE index_type_desc <> 'HEAP' AND fragment_count IS NOT NULL AND avg_fragment_size_in_pages IS NOT NULL ORDER BY 2 GO -- 05_Insert/Update/Delete 大量資料列,四萬筆 SET NOCOUNT ON DECLARE @cnt INT =1 WHILE @cnt < 10001 BEGIN INSERT rowversion_Index1(pid) VALUES('A_'+CAST(SYSDATETIME() AS varchar(50))) INSERT rowversion_Index1(pid) VALUES('B_'+CAST(SYSDATETIME() AS varchar(50))) INSERT rowversion_Index1(pid) VALUES('C_'+CAST(SYSDATETIME() AS varchar(50))) INSERT rowversion_Index1(pid) VALUES('D_'+CAST(SYSDATETIME() AS varchar(50))) INSERT rowversion_NoIndex1(pid) VALUES('A_'+CAST(SYSDATETIME() AS varchar(50))) INSERT rowversion_NoIndex1(pid) VALUES('B_'+CAST(SYSDATETIME() AS varchar(50))) INSERT rowversion_NoIndex1(pid) VALUES('C_'+CAST(SYSDATETIME() AS varchar(50))) INSERT rowversion_NoIndex1(pid) VALUES('D_'+CAST(SYSDATETIME() AS varchar(50))) SET @cnt +=1 END GO -- DELETE:1萬筆 DELETE FROM rowversion_Index1 WHERE pid LIKE 'B_%' GO DELETE FROM rowversion_NoIndex1 WHERE pid LIKE 'B_%' GO -- UPDATE:1萬筆 UPDATE rowversion_Index1 SET pid = ('E_'+CAST(SYSDATETIME() AS varchar(50))) WHERE pid LIKE 'C_%' GO UPDATE rowversion_NoIndex1 SET pid = ('E_'+CAST(SYSDATETIME() AS varchar(50))) WHERE pid LIKE 'C_%' GO -- 05_快速_檢視指定資料庫內的每一個索引之片段(fragmentation)資訊,使用 SAMPLED 模式 SELECT sch.name N'結構描述', obj.name N'資料表', inx.name AS N'索引名稱', index_type_desc N'索引類型', avg_fragmentation_in_percent '片段(%)', avg_page_space_used_in_percent N'頁面飽和度(%)', fragment_count, avg_fragment_size_in_pages, page_count FROM sys.dm_db_index_physical_stats (DB_ID(), NULL,NULL, NULL, 'SAMPLED') AS phy INNER JOIN sys.indexes AS inx ON phy.object_id = inx.object_id AND phy.index_id = inx.index_id INNER JOIN sys.objects AS obj ON phy.object_id = obj.object_id INNER JOIN sys.schemas AS sch ON obj.schema_id = sch.schema_id WHERE index_type_desc <> 'HEAP' AND fragment_count IS NOT NULL AND avg_fragment_size_in_pages IS NOT NULL ORDER BY 2 GO -- 06_觀察:rowversion資料行,有建立索引的使用特性 -- Index Seek SELECT * FROM rowversion_Index1 WHERE rowrev = 0x000000000003AD11 GO -- 07_觀察:rowversion資料行,沒有建立索引的使用特性 - Clustered index Scan SELECT * FROM rowversion_NoIndex1 WHERE rowrev = 0x0000000000024C20 GO
參考資料
認識 資料類型:rowversion,在資料庫內自動產生唯一的二進位數字(1)
http://sharedderrick.blogspot.tw/2016/03/rowversion1.html
沒有留言:
張貼留言