我們有一個狀態表。當狀態改變時,我們當前刪除舊記錄並插入新記錄。刪除並插入或選擇並更新
我們想知道是否會更快地做一個select來檢查它是否存在,然後插入或更新。
儘管與以下問題類似,但它並不相同,因爲我們正在更改單個記錄,而另一個問題是執行總表刷新。
DELETE, INSERT vs UPDATE || INSERT
我們有一個狀態表。當狀態改變時,我們當前刪除舊記錄並插入新記錄。刪除並插入或選擇並更新
我們想知道是否會更快地做一個select來檢查它是否存在,然後插入或更新。
儘管與以下問題類似,但它並不相同,因爲我們正在更改單個記錄,而另一個問題是執行總表刷新。
DELETE, INSERT vs UPDATE || INSERT
您可以使用@@ROWCOUNT並執行UPDATE
。如果它是0行受影響 - 然後執行INSERT
之後,否則不會。
謝謝,這是我們實施的 – 2011-04-13 13:14:12
如果有多個連接同時嘗試同一進程,更新後跟插入可能會中斷 - 他們都嘗試更新,得到0行,然後都嘗試插入和一箇中斷 - 如果你沒有這種併發性問題,那麼很好,但對於一般情況,應該避免。 – 2011-04-13 13:34:53
@Damien_The_Unbeliever:是否合併原子?我想這不是 - 所以它會影響到相同的比賽條件。 – zerkms 2011-04-13 14:01:39
INSERT ... ON DUPLICATE KEY
怎麼樣?首先做一個select來檢查一條記錄是否存在,並檢查你的程序中的結果是否會產生競爭條件。但是,如果只有一個程序實例,那麼在您的情況下可能並不重要。
INSERT INTO users (username, email) VALUES ('Jo', '[email protected]')
ON DUPLICATE KEY UPDATE email = '[email protected]'
您的建議意味着每次狀態更改總是有兩條指令。通常的做法是做一個UPDATE,然後檢查操作是否改變了任何行(大多數數據庫都有一個像ROWCOUNT這樣的變量,如果有變化,它應該大於0)。如果沒有,請執行INSERT。
搜索UPSERT爲尋找模式爲特定的DBMS
我個人認爲Update方法是最好的。不是首先執行SELECT來檢查記錄是否已經存在,您可以先嚐試更新,但如果沒有行受到影響(使用@@ ROWCOUNT),則可以執行INSERT。
原因是遲早你可能想要跟蹤狀態變化,最好的方法是使用狀態表上的觸發器保持所有變化的審計跟蹤。
既然你說的是SQL Server 2008,你有沒有考慮過MERGE?這是一個單一的聲明,允許你做一個更新或插入:
create table T1 (
ID int not null,
Val1 varchar(10) not null
)
go
insert into T1 (ID,Val1)
select 1,'abc'
go
merge into T1
using (select 1 as ID,'def' as Val1) upd on T1.ID = upd.ID --<-- These identify the row you want to update/insert and the new value you want to set. They could be @parameters
when matched then update set Val1 = upd.Val1
when not matched then insert (ID,Val1) values (upd.ID,upd.Val1);
+1,出於某種原因,我只需要喜歡這個答案:) – 2011-04-13 06:57:33
我想更多的信息可能會有所幫助。多少列?主要關鍵是什麼? – 2011-04-13 06:17:12
你使用了什麼確切的dbms? – zerkms 2011-04-13 06:19:59
@zerkms,謝謝你的評論我已更新標籤 – 2011-04-13 06:31:43