UNIQUEIDENTIFIER列上的統(tǒng)計(jì)信息非常有意思,在它上面有一些很令人討厭的行為。我們來(lái)看下。
問(wèn)題重現(xiàn)(The rePRo)為了向你展示我們剛抱怨的行為,我用下列簡(jiǎn)單的表定義創(chuàng)建了一個(gè)數(shù)據(jù)庫(kù),我在UNIQUEIDENTIFIER列上強(qiáng)制主鍵約束。這意味著SQL Server在后臺(tái)會(huì)生成唯一聚集索引,聚集索引本身有一個(gè)統(tǒng)計(jì)信息對(duì)象來(lái)描述那列的數(shù)據(jù)分布情況。當(dāng)然,數(shù)據(jù)分布是線性的,因?yàn)樵赨NIQUEIDENTIFIER列每個(gè)值本身都是唯一的。
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百萬(wàn)條記錄。
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
現(xiàn)在我們用FULLSCAN在表上更新我們的統(tǒng)計(jì)信息。FULLSCAN意味著SQL Server掃描整個(gè)表內(nèi)在數(shù)據(jù)來(lái)更新統(tǒng)計(jì)信息對(duì)象。
1 -- Let's update the Statistics with a FULLSCAN.2 UPDATE STATISTICS CustomersTableGuid WITH FULLSCAN3 GO
但當(dāng)你現(xiàn)在查看統(tǒng)計(jì)信息對(duì)象時(shí),你會(huì)看到在直方圖里SQL Server只生成了4個(gè)步長(zhǎng)。
1 sp_helpindex 'dbo.CustomersTableGuid'2 3 DBCC SHOW_STATISTICS('dbo.CustomersTableGuid', 'PK__Customer__3214EC271273C1CD')
在表頭信息里你可以看到,在統(tǒng)計(jì)信息更新期間,1百萬(wàn)行被采樣,但直方圖只顯示了4個(gè)步長(zhǎng)!但當(dāng)你現(xiàn)在用更小采樣區(qū)間來(lái)更新統(tǒng)計(jì)信息對(duì)象,事情就會(huì)改變:
1 -- Let's update the Statistics with a smaller sampling interval.2 UPDATE STATISTICS CustomersTableGuid WITH SAMPLE 50 PERCENT3 GO
當(dāng)你現(xiàn)在看下直方圖,你會(huì)看到我們有很多不同的步長(zhǎng):
當(dāng)你在數(shù)據(jù)庫(kù)設(shè)計(jì)里用UNIQUEIDENTIFIER列時(shí)要記住這點(diǎn)了。只要這些值是唯一的,你就會(huì)有性能上的問(wèn)題,因?yàn)閷?duì)于直方圖里,你有的巨量區(qū)間,AVG_RANGE_ROW只能做出1行的正確估計(jì)。
感謝關(guān)注!
新聞熱點(diǎn)
疑難解答
圖片精選