2013-06-18 24 views
1

我目前正在對客戶端的MSSQL服務器執行分析。我已經修復了很多問題(不必要的索引,索引碎片,NEWID()被用於所有商店的身份等),但是我遇到了以前從未見過的特定情況。將批量數據獲取到繁忙的表中

進程1將數據導入臨時表,然後進程2使用INSERT INTO複製臨時表中的數據。第一個過程非常快(它使用BULK INSERT),但第二個過程需要大約30分鐘才能執行。在處理2「問題」 SQL如下:

INSERT INTO ProductionTable(field1,field2) 
SELECT field1, field2 
FROM SourceHeapTable (nolock) 

上述INSERT語句的記錄數十萬到ProductionTable,每行分配UNIQUEIDENTIFIER,並插入到5個不同的指標。我很欣賞這個過程需要很長時間,所以我的問題是這樣的:在這個導入過程中,第三個過程負責在ProductionTable上執行不斷的查找 - 除了在表格中插入額外的記錄之外:

INSERT INTO ProductionTable(fields...) 
VALUES(values...) 

SELECT * 
FROM ProductionTable (nolock) 
WHERE ID = @Id 

對於30分鐘左右使INSERT...SELECT以上正在發生,則INSERT INTO倍出。

我的直接想法是SQL服務器在INSERT...SELECT期間鎖定了整個表。在我的分析過程中,我在服務器上進行了很多分析,在INSERT...SELECT期間確實分配了鎖,儘管我不記得它們是什麼類型。

從不需要將記錄同時從兩個源插入表中 - 至少在ETL過程中 - 我不知道如何處理這個問題。我一直在查找INSERT表格提示,但大多數都將在未來版本中過時。

它看起來像我CURSOR是唯一的方式去這裏?

回答

2

您可以考慮Process-2的BULK INSERT以將數據導入ProductionTable。

另一種選擇是將Process-2批量處理成大約1000條記錄的小批量,並使用Table Valued Parameter進行INSERT。參見:http://msdn.microsoft.com/en-us/library/bb510489.aspx#BulkInsert

+0

我確實想過對它進行批處理 - 但再次使用了光標。 我不認爲批量插入適合生產表...我會檢查出來。 – Spikeh

0

看起來像表鎖。

嘗試在ETL過程中插入部分。類似於

while 1=1 
begin 

    INSERT INTO ProductionTable(field1,field2) 
    SELECT top (1000) field1, field2 
    FROM SourceHeapTable sht (nolock) 
    where not exists (select 1 from ProductionTable pt where pt.id = sht.id) 

    -- optional 
    --waitfor delay '00:00:01.0' 

    if @@rowcount = 0 
     break; 

end