SQL Server - 物理表設計 - 列順序 - 空列和非空列
我們正在為新應用程序建構數據庫。我從架構師那裡得到了一些回饋,他在某處讀到,首先將所有不可為空的列放在一個表中,然後是所有可空的列,這對記憶體使用率有好處。如果在不可空列之間存在可空列,則某種記憶體或儲存優勢將被喪失,因為這些可空列位於不可空列之間。
這些列的排序有點模糊,但一般來說,它優先用於更有可能首先使用的列。
我的印像是 SSMS 按其自己的邏輯而不是它們在表上創建的特定順序對頁面文件上的列進行排序。我將列放在表中的順序完全獨立於數據在頁面文件中的儲存方式。
是否有任何文件可以支持這一發現/理解?
編輯:
圍繞弄清楚這個想法的來源進行了更多的對話。該請求過度簡化了具有高密度數據或表中最常用的列
SELECT
或JOIN
操作的列,以防止它們移動到頁面文件的溢出部分。分配給表的列的順序與將數據添加到頁面文件的順序相同。對於給定的行,數據按照列在表中設置的順序儲存在頁面文件中。如果該行包含的數據多於頁面文件允許的數據(假設我們沒有使用任何會進入 LOB
IMAGE
或VARCHAR(MAX)
類似的東西),那麼剩餘部分將被放入溢出文件。如果需要該溢出數據,則需要花費額外的精力和時間來查找該溢出文件。這可能會對高行環境中的性能產生顯著影響(10 或 100 的數百萬行 +)。因此,我們希望按照我們認為該列將被訪問的頻率來確定列順序的優先級,不一定是是否訪問NULL
。這種理解/分析聽起來對嗎?
我將其發佈在這裡作為答案,以便我有更多空間發布資源和連結,並進行一些解釋。
為了回答有關 NULLABLE 與 NON-NULLABLE 列及其相對基數的具體問題,Kimberly Tripp 在這裡有一篇文章:https ://www.sqlskills.com/blogs/kimberly/column-order-doesnt-matter-generally-but-這取決於/
不幸的是,我找不到支持我關於在列順序列表末尾具有可變寬度列的聲明的參考,但原因是在行末尾更新可變寬度列不太可能導致碎片(並且關閉-page 溢出)而不是列順序中間的一個。
但正如我之前所說,這些很難做到正確,除非你確切地知道你的數據訪問模式,否則你可能會弄錯。還有許多其他容易實現的目標來調整擔心列順序的問題。切換到適當大小的靜態列長度將是獲得更好的記憶體估計和避免碎片的更簡單方法。
具有適當填充因子的索引、統計更新、數據訪問的儲存過程(因此您可以更嚴格地控制執行計劃)等等。如果您使用的是企業版,那麼您有更多選擇,表壓縮將允許您將更多數據放入記憶體中,這更容易(並且適用範圍更廣),分區將允許您在管理方面做一些非常酷的事情(儘管使用加快閱讀速度是一項挑戰(分區消除是另一件很難做到的事情))。
請注意,當我說很難做到正確時,我通常的意思是很難讓 SQL 充分利用它們,因此花在優化上的時間通常會更好地花在其他地方來獲得 ROI。
在編輯部分回答問題的最後一部分。是的,使用主鍵、外鍵和其他連接列預載入列可能會有所幫助。但是,如果您對這些有索引,那麼它應該無關緊要,因為索引將用於確定要檢索哪些行,然後執行 keylookup。我只是不認為在它上面花費架構時間是值得的。在任何情況下,您都可能會對這些列建立索引。