2013-05-14 50 views
6

我有數據是一個整數值的矩陣,它表示一個帶狀分佈曲線。 我正在優化SELECT性能而非INSERT性能。有最多100個樂隊。 我主要是在一段時間內通過求和或求平均值來查詢這些數據。將行標準化爲列可以增強SQL Server的性能嗎?

我的問題是,我可以實現更好的性能通過將這些數據展平成一列,每列帶1列,或者使用表示帶值的單列表示?

展數據

UserId ActivityId DateValue Band1 Band2 Band3....Band100 
10001 10002  1/1/2013 1  5  100  200 

或正火

UserId ActivityId DateValue Band BandValue 
10001 10002  1/1/2013 1 1 
10001 10002  1/1/2013 2 5 
10001 10002  1/1/2013 3 100 

樣品查詢

SELECT AVG(Band1), AVG(Band2), AVG(Band3)...AVG(Band100) 
FROM ActivityBands 
GROUP BY UserId 
WHERE DateValue > '1/1/2012' AND DateValue < '1/1/2013' 

回答

8

以標準化格式存儲數據。

如果您沒有從該方案中獲得可接受的性能,而不是反規範化,請首先考慮您在該表上具有的索引。你很可能會錯過一個索引,使得它的表現類似於非規範化表。接下來,嘗試編寫查詢以從規範化表中檢索數據,以使結果集看起來像非規格化表,然後使用該查詢創建indexed view。這將使您選擇與非規範化表相同的性能,但保留適當規範化的良好數據組織優勢。

1

如果您想獲取數據非常快,那麼你應該變平表和使用索引以改善與您所提議的相似的廣泛色譜柱範圍的選擇。但是,如果您有興趣構建數據以進行快速更新,那麼使用第3級或第4級標準化與大量表連接相結合可以提供更好的性能。

2

如果您正在訪問每行中的所有(或大部分)帶,那麼非規範化形式會更好。我的經驗更好。

原因很簡單。頁面中數據的大小要小得多,因此需要閱讀更少的頁面才能滿足查詢。每行存儲一個帶寬的開銷約爲4個整數或32個字節。所以,100個波段大約是3200字節。在單個記錄中,記錄大小爲100 * 4 + 8或大約408個字節。如果您的查詢正在讀取大量記錄,則會顯着降低I/O需求。

有一個警告。如果您只讀取一條記錄,則100條記錄適合SQL中的單個頁面,一條記錄適合單個頁面。在兩種情況下,單頁讀取的I/O可能相同。好處是您閱讀的數據越來越多。

您的示例查詢正在讀取數百或數千行,因此非規範化應該有益於此類查詢。

4

反規範化優化了一種訪問數據的方法,但犧牲了(幾乎所有)其他的功能。

如果您只有一個訪問方法對性能至關重要,則非規範化可能會有所幫助;儘管適當的指數選擇具有更大的好處。但是,如果您有多個針對數據的性能關鍵訪問路徑,則最好尋求其他優化。

創建適當的聚集索引;把你的非聚集索引放在SSD上。增加服務器的內存;所有這些技術都將提高全部 *訪問的性能,而不是在各種訪問之間進行權衡。