2017-06-29 33 views
0

我正在更新舊的存儲過程(它調用其他子存儲過程)。在事務中,它處理大約十幾個表中的數據,並在進程,有時會觸發鎖升級到表鎖。在某些情況下,此過程可能需要20分鐘或更長時間才能完成。很顯然,鎖定桌子很長時間是一件很不錯的事情。因此,我正在制定一個2階段計劃,以減少由第1階段引起的阻塞,並將其完全重寫爲更高效,並且不會在階段2中花費過多的時間。臨時表需要唯一索引名稱

爲了減少阻塞,無論在哪裏對數據庫表進行操作,我都計劃將該操作移到臨時表中。通過完成臨時表中的所有工作,然後在流程的最後階段以最終結果更新實際表格,我應該可以顯着減少阻止其他用戶的時間。 (這是第一階段的「快速修復」。)

這是我的問題:當我使用它們進行各種計算時,這些臨時表中的某些可能有100,000行或更多行。正因爲如此,我想在臨時表上生成索引以保持性能。由於這些是在存儲過程中創建的臨時表,因此如果多個用戶同時執行sproc,則它們需要具有唯一的名稱以避免錯誤。我知道我可以使用CREATE TABLE語句手動聲明臨時表,如果我這樣做,我可以指定一個沒有名稱的索引,並讓SQL Server爲我創建名稱。我希望能夠做的是使用SELECT * INTO生成臨時表,並找到另一種方式讓SQL Server自動生成索引名稱。我確定你在問「爲什麼?」我的公司在與我合作的系統中有幾處商店更改。如果我可以設法使用SELECT INTO方法,那麼,如果列被添加或調整大小等,那麼開發人員就不需要知道他們必須回到這些存儲過程並更改它們臨時表定義匹配。使用SELECT INTO將自動保持臨時表匹配「真實」表格的佈局。

那麼,有沒有人知道一種方法來讓SQL Server自動爲臨時表上的索引生成名稱(除了將其作爲CREATE TABLE語法的一部分執行)?

謝謝!

+0

只有當您創建約束時,每個會話都必須具有唯一的約束名稱。如果你只是創建獨特的索引,它會沒事的。您可以運行test @DavidBrowne示例,更改以創建唯一索引。 – Wendy

+0

只要你不指定索引,你應該沒問題。 –

回答

1

由於這些是在存儲過程中創建的臨時表,因此如果多個用戶同時執行sproc,它們需要具有唯一名稱以避免錯誤。

不,他們沒有。每個會話都有自己的臨時表,並且會自動清理。

索引沒有全局名稱範圍,所以每個臨時表可以具有相同的索引名稱。例如

create procedure TempTest 
as 
begin 
    select * into #t from sys.objects 
    create index foo on #t(name) 
    waitfor delay '00:00:10' 
    select * from #t 
end 

而且你可以從多個會話中運行

exec temptest 
go 10 

+0

D'oh!你會看看那個。謝謝。原來我的問題是基於一個無效的前提。 – DeadZone