2008-11-13 53 views
5

我們有一個系統同時插入來自多個工作站的大量數據,同時還暴露了一個數據查詢接口。該模式看起來是這樣的(約窮人格式不好意思):事務級別,nolock/readpast和併發

[SyncTable] 
    SyncID 
    StationID 
    MeasuringTime 


[DataTypeTable] 
    TypeID 
    TypeName 


[DataTable] 
    SyncID 
    TypeID 
    DataColumns... 

數據插入一個「同步」做,是這樣的(我們只將數據插入到系統中,我們從來沒有更新)

INSERT INTO SyncTable(StationID, MeasuringTime) VALUES (X,Y); SELECT @@IDENTITY 

INSERT INTO DataTable(SyncID, TypeID, DataColumns) VALUES 
    (SyncIDJustInserted, InMemoryCachedTypeID, Data) 
    ... lots (500) similar inserts into DataTable ... 

和查詢是這樣的(對於一個給定站,measuringtime和數據類型)

SELECT SyncID FROM SyncTable WHERE StationID = @StationID 
           AND MeasuringTime = @MeasuringTime 
SELECT DataColumns FROM DataTable WHERE SyncID = @SyncIDJustSelected 
            AND DataTypeID = @TypeID 

我的問題是我們如何能夠在刀片和NOLOCK/READP結合事務級在查詢AST提示,以便:

  1. 我們最大限度的併發在我們的系統,同時有利於插入(我們需要存儲大量的數據,一些高達2000+記錄第二)
  2. 只查詢返回來自「提交」同步的數據(我們不希望結果集有一半插入同步或由於跳過鎖定而與一些跳過的條目同步)
  3. 我們不在乎是否包含「最新」數據在查詢中,我們更關心一致性和響應性,然後針對「實時」和最新數據

這可能是非常矛盾的目標,可能需要很高的事務隔離級別,但我對所有技巧和優化感興趣,以實現對插入和選擇的高響應性。我很樂意詳細說明是否需要更多細節來清除更多的調整和技巧。

更新:爲未來的回覆添加更多信息。我們正在運行SQL Server 2005(可能在六個月內於2008年)在最初具有5+ TB存儲的SAN網絡上運行。我不確定SAn設置了什麼樣的RAID,以及我們有多少可用的磁盤。

回答

0
  1. 你會使用什麼類型的磁盤系統?如果你有一個大的條帶RAID陣列,寫入應該會表現良好。如果您可以估計每秒鐘所需的讀寫次數,則可以將這些數字插入公式中,並查看您的磁盤子系統是否會保持不變。也許你無法控制硬件...

  2. 難道你不會在事務中包裝插入,這將使它們無法讀取,直到插入完成?

  3. 如果你的硬件配置正確,並且你注意到你的SQL編碼 - 這看起來應該是這樣,這應該遵循。

查找到SQLIO.exe和SQL應力工具:

SQLIOStress.exe SQLIOStress.exe模擬的SQL Server 2000的I/O行爲的各種圖案,以保證基本的I/O安全。

可以從Microsoft網站下載SQLIOStress實用程序。請參閱下面的文章。

•如何使用SQLIOStress實用程序來應力磁盤子系統如SQL Server http://support.microsoft.com/default.aspx?scid=kb;en-us;231619

重要下載包含一個完整的白皮書有關該實用程序擴展細節。

SQLIO.exe SQLIO.exe是SQL Server用於建立基本的基準測試結果2000 I/O實用工具。

的SQLIO實用程序可以從微軟網站下載。請參閱以下內容: •SQLIO性能測試工具(SQL開發) - 客戶可用 http://download.microsoft.com/download/f/3/f/f3f92f8b-b24e-4c2e-9e86-d66df1f6f83b/SQLIO.msi

+0

將此標記爲答案,因爲「解決方案」的一部分與正確設置特定磁盤系統有關,這極大地提高了吞吐量 – 2009-10-14 09:03:10

1

如果您正在運行SQL 2005和上述外觀到實施snapshot isolation。您將無法使用nolock獲得一致的結果。

在SQL 2000解決這個困難得多。

1

這是SQL Server 2005/2008企業的分區特性有很大的場景。您可以爲每個的stationID一個分區,每個的stationID的數據可以進入自己的文件組(如果你想,這取決於你的負載可能沒有必要。)

這給你買了併發的一些優點:

  • 如果您通過stationid進行分區,則用戶可以爲當前未加載的stationid運行選擇查詢,並且它們不會遇到任何併發問題
  • 如果通過stationid進行分區,則多個站點可以插入數據同時沒有併發問題(只要他們是在不同的文件組)
  • 如果您通過syncid範圍進行分區,則可以將較舊的數據放在較慢的存儲上。
  • 如果通過syncid範圍分區,如果你的範圍足夠小(意爲不與成千上萬syncids的範圍內),那麼你可以做在同一時間你的用戶查詢的負載,而不會在併發問題

您所描述的情況有很多共同的數據倉庫夜間負荷。微軟做了一個名爲Project Real的技術參考項目,您可能會感興趣。他們發表它作爲一個標準,你可以通過設計文檔和代碼的執行順序讀取,看看他們是怎麼做到過的真快負載:

http://www.microsoft.com/technet/prodtechnol/sql/2005/projreal.mspx

分區,甚至更好在SQL Server 2008中,特別是圍繞併發。它仍然不是銀彈 - 它需要熟練的DBA進行手動設計和維護。這不是一個「即忘即忘」功能,它需要企業版,其價格高於標準版。不過,我喜歡它 - 我已經多次使用它,併爲我解決了特定的問題。

+0

通過stationid進行分區的另一個優點:如果創建正確的聚簇索引(stationid,syncid)在synatable上,(syncid)在datatable上,並且爲syncid使用標識,你永遠不會從插入活動中獲得頁面分割,這允許你在select語句上使用READPAST,這樣就不會干擾插入活動不要等待爲X鎖定記錄獲取S鎖,並且不更新時,不會爲任何S鎖定行發出X鎖。如果可以分頁,READPAST有時會導致不一致的結果,這是一個危險的選擇。 – TToni 2013-09-09 15:41:43