本文介紹了選擇所有數(shù)據(jù)后,Sql服務器將刪除的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我添加了一個存儲過程,用于刪除和插入特定表的數(shù)據(jù),但SELECT的執(zhí)行時間可能需要10分鐘才能完成,因此在此期間我的表是空的
如何修改我的存儲過程以在它完成時選擇所有需要的數(shù)據(jù)?在目標表上刪除當前數(shù)據(jù)并插入所選數(shù)據(jù)?
這是我的代碼
delete from table_b
insert into table_b(id,name,km)
select id,t.name,t.kmfrom table_a
OUTER APPLY (select * from dbo.calculate(table_a.CoordonneeX,table_a.CoordonneeY)) as t
推薦答案
打個比方:
你在當?shù)剞r貿市場賣的蔬菜擺滿了桌子。
當你帶來一批新的蔬菜時,你需要20分鐘來清理桌子,用新的產品取代庫存。
您不希望客戶坐在那里等20分鐘等待切換發(fā)生(大多數(shù)人只會從其他人那里購買蔬菜)。
如果您有第二張空桌子,在那里您裝滿了新蔬菜,而在這樣做的同時,客戶仍然可以從第一張桌子上買到較舊的蔬菜,情況會怎樣?(讓我們假設這不是因為舊蔬菜變壞了,或者其他原因不太受歡迎。)
有多種方法可以滿足您的場景。基本概念是:
您有第二個在后臺加載的影子表。
當此后臺加載發(fā)生時,用戶將繼續(xù)看到第一個表中較舊的數(shù)據(jù)。
后臺加載完成后,您可以通過以下方式將用戶重定向到數(shù)據(jù)更新的第二個表:
重命名
更改同義詞或視圖以指向新表
在架構之間傳輸(請參閱here和here)
partition switching(盡管普遍認為,不需要企業(yè)版)
我一直喜歡使用模式來解決這一問題,但分區(qū)切換是最好的解決方案,因為其他三種解決方案需要更積極的模式修改鎖,不允許以較低的優(yōu)先級等待,并且有更大的風險使任何現(xiàn)有的統(tǒng)計/執(zhí)行計劃無效或不那么準確。所有這些解決方案的一個問題是,如果有指向主表的外鍵,則無論您的計劃的一部分是清空父表,都必須處理這一問題。
大量借用Kendra的gist,因為我很懶,而她在那里做得很好,讓我們創(chuàng)建原始表的兩個副本,一個用于處理傳入的新數(shù)據(jù),另一個用于接受舊數(shù)據(jù):
CREATE TABLE dbo.MyTable
(
id int NOT NULL,
description varchar(32)
);
INSERT dbo.MyTable(id, description) VALUES(1, 'old data');
CREATE TABLE dbo.MyTable_Staging
(
id int NOT NULL,
description varchar(32)
);
CREATE TABLE dbo.MyTable_Garbage
(
id int NOT NULL,
description varchar(32)
);
SELECT * FROM dbo.MyTable;
(這是一個非常簡單的模型–當然,您的實際表會有匹配的主鍵、索引、約束等。)
現(xiàn)在,我們可以在后臺加載臨時表,完成后,將當前數(shù)據(jù)切換到垃圾表,然后將臨時表切換到主表。
-- perform the background loading outside of any blocking transaction:
TRUNCATE TABLE dbo.MyTable_Garbage;
TRUNCATE TABLE dbo.MyTable_Staging;
INSERT dbo.MyTable_Staging(id, description)
VALUES(1, 'new data'),(2, 'new row!');
BEGIN TRANSACTION;
ALTER TABLE dbo.MyTable
SWITCH TO dbo.MyTable_Garbage
WITH ( WAIT_AT_LOW_PRIORITY
( MAX_DURATION = 1 MINUTES, ABORT_AFTER_WAIT = BLOCKERS)
);
ALTER TABLE dbo.MyTable_Staging
SWITCH TO dbo.MyTable;
COMMIT TRANSACTION;
SELECT * FROM dbo.MyTable;
我在db<>fiddle中演示了這一點,只是那里的權限不允許我們?yōu)閿r截器指定等待較低優(yōu)先級選項,這在規(guī)模上將是重要的。為了簡單起見,也沒有錯誤處理,但這并不意味著不需要它。(感謝@CharlieFaces指出,PARTITION 1
對于未分區(qū)的表是不必要的。)
您也可以更快地清理垃圾,就像在提交后立即清理垃圾一樣,但保留垃圾可以讓您在出現(xiàn)某種問題時進行故障排除或恢復。
這篇關于選擇所有數(shù)據(jù)后,Sql服務器將刪除的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,