我有兩個表T_A
和T_B
。並行SQL Server聚簇索引創建
- 兩者都是空的。
- 它們都有聚簇索引。
- 恢復模式設置爲
SIMPLE
。 - insert ... select ..符合最小日誌記錄的要求。請參閱 http://msdn.microsoft.com/en-us/library/ms191244.aspx
- 兩個登臺表都包含大量數據。
我需要從登臺表導入數據。
如果我單獨執行以下T-SQL塊,每個需要2到3分鐘才能完成。總時間約爲5至6分鐘。
BEGIN TRAN
INSERT INTO T_A WITH(TABLOCK) FROM SRC_A WITH(NOLOCK);
COMMIT TRAN
BEGIN TRAN
INSERT INTO T_B WITH(TABLOCK) FROM SRC_B WITH(NOLOCK);
COMMIT TRAN
爲了讓我更快地打開SMSS兩會和並行執行兩個街區。令我驚訝的是,每場會議大約需要10到12分鐘才能完成。總共花費的時間增加了一倍多。顯示的wait_type
是PAGEIOLATCH_SH
,它指向磁盤I/O瓶頸。我不明白的是,即使兩個會話必須等待I/O,它也不應該等待那麼久。任何人都可以解釋這個嗎?
我的故事還沒有結束呢。然後,我刪除了兩個表上的聚簇索引,並在不同的會話中並行運行了兩個塊。這一次大約需要1分鐘才能完成。自平行以來,總時間約爲1分鐘。大!但是當我嘗試創建聚簇索引時,噩夢即將到來。
如果我單獨創建羣集索引,則每個完成需要4分鐘。總時間約8分鐘。這打敗了我改善表現的目的。
然後我嘗試在兩個表上並行創建聚集索引,每個在不同的會話上。這一次是最糟糕的:一次需要12分鐘才能完成,另一次需要25分鐘才能完成。
從我的測試結果中,我最好的選擇是回到原來的一個方法:依次在表上使用聚簇索引執行兩個事務。
有沒有人遇到類似的情況,以及使其更快的最佳做法是什麼?
我沒有什麼可以支持的,但我的猜測是你的第一個測試用例有I/O順序的優點...這意味着磁盤上的磁頭不必跳過所有的地方......在所有其他測試案例中,I/O都是隨機的,這意味着磁頭爲您的一個表格寫入一個塊,然後跳轉到磁盤上的另一個位置爲另一個表寫入不同的塊,並且像這樣來回......這就是爲什麼並行執行比順序執行需要更長的時間。 –
刪除WITH(TABLOCK)提示是否可以提高平行插入速度? SRC_A和SRC_B中的數據可能碰到聚集索引的不同區域還是相同區域? –
感謝您的回覆。刪除WITH(TABLOCK)將無濟於事,因爲這將使插入變爲完全記錄。而這兩張表格完全不同。他們的集羣鍵列完全不同。 – Shawn