儲存 VarChar(Max)ñ奧特斯___ñ這噸和sNotes同一表或單獨表上的列
免責聲明
不久前我有一個桌子設計的想法,當時對我來說很有意義。在最近的歷史中,我意識到我有“過度設計”或花費太多時間試圖“過度優化”解決方案的習慣。我假設這是我過度思考解決方案並且會產生額外成本而幾乎沒有實際收益的情況之一。
問題
假設一個對象(
Shipment
table
例如 a)有某種NOTE
varchar(MAX)
我們想要跟踪的數據元素。NOTE
column
有機會將數據推入溢出並顯著增加大小row
(從而限制rows
可以保存在 上的數量page
)。據我了解,這會對整個表上各種操作的執行時間產生負面影響。有沒有一個例子,我們應該把它推
column
到一個單獨的獨立設備上,ShipmentNote
table
而不是把它column
放在Shipment
table
. 理論是,如果我們將其推NOTE
column
入一個單獨table
的位置,它會保存pages
on,Shipment
table
這使得所有操作都Shipment
table
可以更好地執行。因為row
尺寸更小,現在您可以rows
在相同的尺寸上安裝更多page
。(請參見下面的架構範例):
這可能是一個好主意的主要案例是:
Note
column
通常超過 8000 個字元(我認為這是我們開始使用額外分頁的時候)- 操作中
Note
column
唯一返回的,SELECT
很少或從不用作JOIN
or的一部分WHERE
- 其餘
columns
的Shipment
將被Note
定期獨立查詢(即:我們的大部分操作,不會使用Note
,JOIN
或者WHERE
其他發生columns
在“裝運”中的情況)我看到的缺點(除此之外,在使用列
Shipment
外的表格時可能實際上並沒有明顯的改進Note
):
- 現在變得不可能(或至少需要 a
trigger
或其他東西)確保總是有某種價值NOTE
(即:因為它現在是單獨的child table
,我們無法確保它NOTE
適用於NOT NULL
每個row``Shipment
- 現在使用任何操作
NOTE
都需要額外的努力,因為需要做一個JOIN
以確保我們正在使用正確的記錄
儘管您甚至在考慮這一點都很棒-我認為這是微優化。SQL Server 已經內置了用於處理的優化
NVARCHAR(MAX)
,所以通常我會說不要再猜測它,直到它成為一個問題。但是,在閱讀您的問題時,我想到了兩個要點。第一個是(正如您在最後一點提到的那樣)實際上是否會通過將數據拆分到另一個表中而不是讓 SQL Server 優化頁面和數據本身來獲得任何性能?我現在沒有確鑿的證據,但我懷疑沒有。原因是,正如您所提到的,您的數據通常超過 8000 字節,因此無論如何都會移動到 Note 表中的 LOB 頁面。您只是將感知到的問題從一張桌子轉移到另一張桌子。加上必須獲取數據時執行的成本,
JOIN
您最終可能會比開始時的情況稍差。其次,當您使用數據庫設計標記問題時,我的實際建議是將註釋拆分到另一個表中。但是,我的推理不是由性能優化驅動,而是更具體地說是為應用程序增加了靈活性。一件貨物很可能需要附上一張以上的票據(例如,如果它在運輸途中延誤,或者客戶來電等……)。如果您有關於實際貨物本身的註釋,則在不複製數據的情況下很難做到這一點。如果您將其提取到自己的表格中,您將能夠為一個貨件分配多個註釋,並跟踪誰輸入它們以及何時輸入它們。這使您的應用程序和數據庫更加靈活。
如果您想優化,那麼我建議您無需查詢註釋,除非有人特別想查看它們(例如在您的應用程序中有一個專用表單來執行此操作)。這樣,您只需要在有人明確想要查看數據時執行連接/查找。即使您沒有將註釋外部化到另一個表,如果不需要在查詢中不包括該列,SQL Server 也無需讀取 LOB 頁面。如果可能的話,我總是會優化查詢以在微觀層面進行優化之前返回所需的最少資訊量。