1. 程式人生 > >設計表的時候,對變長字段長度選擇的一點思考

設計表的時候,對變長字段長度選擇的一點思考

eight CA serve 可能 執行 滿足 ide ont val

不管是在MSSQL還是MySQL或者Oracle,變長字段的長度衡量都是要經常面對的。
對於一個變長的字段,在滿足業務的情況下(其實所謂的滿足業務是一個比較模糊的東西),到底是選擇varchar(50)還是varchar(200)亦或是varchar(500)?
對於保守型選擇,往往是選擇一個較大的長度,比如varchar(500)要比varchar(50)更具有兼容性,因為是變長字段的原因,存儲空間也一樣。
這樣的選擇並不能說就不好,看站在哪個角度來看問題。
那麽,相對於varchar(50),varchar(500)在更具備兼容性的同時,有哪些不好的地方,也是需要思考的,。

這裏的原則就是:對於可變長度的字段,在滿足條件的前提下,盡可能使用較短的變長字段長度。

以下是一個相對極端的例子,以SQL Server為例,
TestVarchar1和TestVarchar2的SortColumn 字段長度分別是varchar(50)和varchar(8000),兩個表寫入10000條測一樣的試數據,
SortColumn 的實際長度是36個字符。

Create Table TestVarchar1
(
    Id INT IDENTITY(1,1),
    SortColumn varchar(50)
)

Create Table TestVarchar2
(
    Id INT IDENTITY(1,1),
    SortColumn 
varchar(8000) ) DECLARE @SortColumn char(36); set @SortColumn = CAST(NEWID() as char(36)) insert into TestVarchar1(SortColumn) values (@SortColumn) insert into TestVarchar2(SortColumn) values (@SortColumn) GO 10000

1,基於存儲空間的考慮

存儲空間上,存儲不超過一定長度的變長字段,不同長度的變長字段存儲空間是一樣的,比如選擇使用varchar(50)和varchar(500)是一樣的,

也就說,對於不超過50個字符串的數據存儲,兩者在物理空間占用上並沒有區別。

這裏會發現,兩個表的數據在完全一致的情況下,其存儲空間也是完全一樣的,的確,並不會因為varchar使用一個較長的長度而多占用存儲空間

技術分享圖片

2,基於性能的考慮
選擇varchar(50)還是varchar(8000),在性能上確實有顯著的差異,考慮到某些查詢需要內存(Memory Grant),查詢引擎會預估當前查詢需要的內存,影響查詢內存的因素有以下幾個方面
1,查詢的類型,有沒有聚合運算,有沒有排序等等
2,每個操作符涉及到的記錄數量
3,數據行的大小(這裏是字段類型的長度而不是字段實際長度)
當行記錄的數據類型長度較大的時候,執行計劃預估的平均大小較大,數據類型定義的長度越大,預估的長度越大,需要分配的內存越大
如果一個查詢涉及一些聚合操作並且數據量較大,就可能需要大量的內存來完成這個查詢,查詢引起會分配多余實際需要的內存。

兩者對數據行Size的預估是一樣的(盡管是完全一樣的數據)

技術分享圖片技術分享圖片

造成的結果就是兩個查詢的內存授予是一樣的,同時第二個執行計劃還有一個警告信息(黃色的感嘆號)

技術分享圖片技術分享圖片

以上可以看出,盡管兩個表的數據是完全一致的,
不過字段的最大長度不一致,造成執行計劃預估出現較大的偏差,因此給予較高的內存,浪費無所謂的資源。

再看一個通過聚合函數操作兩張表的例子,會增加CPU的使用。

技術分享圖片技術分享圖片

因此對於可變長度的字段,在滿足條件的前提下,盡可能使用較短的變長字段長度。

設計表的時候,對變長字段長度選擇的一點思考