2012-09-04 66 views
1

我們有以下架構表:與優化的批量插入表性能和查詢

CREATE TABLE Measurement (
    HubId bigint NOT NULL 
    ,DeviceId bigint NOT NULL 
    ,Timestamp datetime NOT NULL 
    ,Value bigint NOT NULL 
) 

我們想記錄導入到這個表約100,000條記錄第二,這將在多個被分割併發連接。我可以通過將表格視爲堆(即無索引)並使用SqlBulkCopy來實現此級別的性能。每秒有100000個獨特的HubIdDeviceId組合與Timestamp遞增。隨着時間的推移,Value是累積的。

我們還需要讀取最近兩次(在這種情況下,倒數第二個和倒數第二個 - 插入總是按順序)值GROUP BY HubId, DeviceId每秒一次,但僅限於行的子集(用戶是感興趣的)產生最後兩個值之間的實時差異。

另外,我們需要將數據每15分鐘彙總一次到15分鐘的時間段以用於歷史目的。根據前15分鐘切片的最大值和當前15分鐘切片的最大值彙總此數據......這需要在整個數據集中進行,但可以跨多個連接進行分割,以獲得獨特的HubIdDeviceId組合。因爲Value是累計的,所以這實際上是上一個和當前15分鐘切片的最後一個值。

使用索引向表中批量插入會導致升級到獨佔表鎖。另外,我們似乎無法讓查詢在不升級到獨佔表鎖的情況下執行。

任何人都可以給我一些關於結構化的最佳方式的指針嗎?我敲我的頭撞在牆上試圖找出去的最佳途徑......

感謝, 院長

+1

可能是值得嘗試[表分區(http://databases.about.com/od/sqlserver/a/partitioning.htm) – Andomar

+0

謝謝,我要一看 –

回答

0

所以經過多少-ING來回-ING,我們已經有所改變我們的方法以實現我們所需的吞吐量。事實證明,我們只關心每秒10萬條記錄,並且它們用於更新持續滾動的彙總和實時值。

我們使用大量工作線程將100,000行批量插入臨時堆表(因此使用4個工作線程,每個線程處理大約25,000行),然後將聚集索引應用於臨時表。然後,我們將來自臨時表的數據直接合併到實時表和聚合表中並刪除臨時表。這裏我們使用ROWLOCK提示強制SQL採用ROWLOCK而不是TABLOCK或PAGLOCK,這會在工作線程中造成比必要的更大的爭用。

另外,我們將內存中的數據結構更改爲有損堆棧而非隊列。在我們的情況下,這是合適的,因爲我們通常只關心最新的數據,並且可以刪除舊數據。

我們將使用分區作爲我們口袋裏的ace,但是我們目前僅限於SQL Server標準版,所以我們現在不能在我們的開發機器之外部署它。

乾杯, 院長