UNIQUEIDENTIFIER列上的統計信息非常有意思,在它上面有一些很令人討厭的行為。我們來看下。
問題重現(The rePRo)為了向你展示我們剛抱怨的行為,我用下列簡單的表定義創建了一個數據庫,我在UNIQUEIDENTIFIER列上強制主鍵約束。這意味著SQL Server在后臺會生成唯一聚集索引,聚集索引本身有一個統計信息對象來描述那列的數據分布情況。當然,數據分布是線性的,因為在UNIQUEIDENTIFIER列每個值本身都是唯一的。
1 -- Create a new table with a UNIQUEIDENTIFIER column as primary key.2 -- SQL Server will enforce the primary key constraint through unique clustered index in the background.3 CREATE TABLE CustomersTableGuid4 (5 ID UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,6 FirstName VARCHAR(50),7 LastName VARCHAR(50)8 )9 GO
下一步我往表里插入1百萬條記錄。
1 -- Insert 1 million records 2 DECLARE @i INT = 0 3 WHILE (@i <= 1000000) 4 BEGIN 5 INSERT INTO CustomersTableGuid (ID, FirstName, LastName) 6 VALUES 7 ( 8 NEWID(), 9 'FirstName' + CAST(@i AS VARCHAR),10 'LastName' + CAST(@i AS VARCHAR)11 )12 13 SET @i +=114 END15 GO
現在我們用FULLSCAN在表上更新我們的統計信息。FULLSCAN意味著SQL Server掃描整個表內在數據來更新統計信息對象。
1 -- Let's update the Statistics with a FULLSCAN.2 UPDATE STATISTICS CustomersTableGuid WITH FULLSCAN3 GO
但當你現在查看統計信息對象時,你會看到在直方圖里SQL Server只生成了4個步長。
1 sp_helpindex 'dbo.CustomersTableGuid'2 3 DBCC SHOW_STATISTICS('dbo.CustomersTableGuid', 'PK__Customer__3214EC271273C1CD')
在表頭信息里你可以看到,在統計信息更新期間,1百萬行被采樣,但直方圖只顯示了4個步長!但當你現在用更小采樣區間來更新統計信息對象,事情就會改變:
1 -- Let's update the Statistics with a smaller sampling interval.2 UPDATE STATISTICS CustomersTableGuid WITH SAMPLE 50 PERCENT3 GO
當你現在看下直方圖,你會看到我們有很多不同的步長:
當你在數據庫設計里用UNIQUEIDENTIFIER列時要記住這點了。只要這些值是唯一的,你就會有性能上的問題,因為對于直方圖里,你有的巨量區間,AVG_RANGE_ROW只能做出1行的正確估計。
感謝關注!
新聞熱點
疑難解答