2015-04-01 1397 views
0

我有大表(7000萬條記錄),這也是索引嚴重(5個索引),我需要與它合併大約100 000條記錄(幾個連續數次)。所以我做了合併和一些合併是好的,並且有些返回SQL Server數據庫引擎的實例目前無法獲得LOCK資源

此時SQL Server數據庫引擎的實例無法獲得LOCK資源。在活動用戶較少時重新運行您的聲明。請數據庫管理員檢查此實例的鎖定和內存配置,或檢查長時間運行的事務。

合併中沒有任何事務,並且從實體框架(v 4.0)中調用(作爲存儲過程)也沒有任何事務。

using (var b = new MyEntities()) 
{ 
    b.CommandTimeout = 36000; 
    b.Merge_My_Stuff(); 
} 

此外服務器具有的RAM 16 GB(其中大部分是採取由SQL Server),在該表中的數據是2.5 Gb和索引7 GB。 我查看了內存限制,他們是

max server memory (MB) 2147483647 2147483647 Maximum size of server memory (MB) 
min server memory (MB) 0 16 Minimum size of server memory (MB) 

任何意見,將不勝感激。此外,爲什麼SQL Server需要這麼多的鎖進行合併?

編輯 MERGE語句是(執行計劃,我會在以後添加)

merge Target_table as target 
using (select * from I_Tmp) as source 
on target.A_ID = source.A_ID and 
    target.B_ID = source.B_ID and 
    isnull(target.C_ID, 0) = isnull(source.C_ID, 0) 
when not matched by target then 
    insert(A_ID, B_ID, C_ID, D, E) 
    values(source.A_ID, source.B_ID, source.C_ID, D, E) 
when matched then 
    update 
    set D= source.D, 
     E= source.E; 

delete from I_Tmp 
+1

請添加實際的合併聲明並理想地執行它的執行計劃 – 2015-04-01 10:57:36

+1

嘗試一次執行多個較小的批次,而不是100K。 – gvee 2015-04-01 11:13:39

+0

看起來鎖定升級已禁用。爲什麼SQL Server需要上百萬個鎖?檢查表選項和跟蹤標誌。 SQL Server完全可以在一個語句中編寫7千萬行。完全沒有麻煩。 – usr 2015-04-01 11:50:00

回答

1

看起來像一個鎖定超時錯誤。它可能與服務器內存無關,而是由與其他線程的爭用引起的。

這裏有一對夫婦的事情,可能會幫助:

  1. 確保索引所有的合併條件(A_ID,B_ID,C_ID)作爲鍵(甚至更好的存在,如果你的聚集索引這些作爲其鍵)
  2. 減少批量大小顯著

如果無法降低批量大小,可以考慮使用TABLOCK/TABLOCKX提示您的MERGE語句。由於批量較大,無論如何,SQL可能會將您的鎖升級爲表鎖,從而增加事務處理時間。直接進入表鎖可以減輕超時。

+0

與(tablockx)做了詭計 – ren 2015-04-03 15:49:21