2011-04-13 91 views
0

我們有一個狀態表。當狀態改變時,我們當前刪除舊記錄並插入新記錄。刪除並插入或選擇並更新

我們想知道是否會更快地做一個select來檢查它是否存在,然後插入或更新。

儘管與以下問題類似,但它並不相同,因爲我們正在更改單個記錄,而另一個問題是執行總表刷新。

DELETE, INSERT vs UPDATE || INSERT

+0

我想更多的信息可能會有所幫助。多少列?主要關鍵是什麼? – 2011-04-13 06:17:12

+0

你使用了什麼確切的dbms? – zerkms 2011-04-13 06:19:59

+0

@zerkms,謝謝你的評論我已更新標籤 – 2011-04-13 06:31:43

回答

1

您可以使用@@ROWCOUNT並執行UPDATE。如果它是0行受影響 - 然後執行INSERT之後,否則不會。

+0

謝謝,這是我們實施的 – 2011-04-13 13:14:12

+0

如果有多個連接同時嘗試同一進程,更新後跟插入可能會中斷 - 他們都嘗試更新,得到0行,然後都嘗試插入和一箇中斷 - 如果你沒有這種併發性問題,那麼很好,但對於一般情況,應該避免。 – 2011-04-13 13:34:53

+0

@Damien_The_Unbeliever:是否合併原子?我想這不是 - 所以它會影響到相同的比賽條件。 – zerkms 2011-04-13 14:01:39

1

INSERT ... ON DUPLICATE KEY怎麼樣?首先做一個select來檢查一條記錄是否存在,並檢查你的程序中的結果是否會產生競爭條件。但是,如果只有一個程序實例,那麼在您的情況下可能並不重要。

INSERT INTO users (username, email) VALUES ('Jo', '[email protected]') 
ON DUPLICATE KEY UPDATE email = '[email protected]' 
+0

競爭條件可以用唯一約束來解決。 – zerkms 2011-04-13 06:21:22

+0

只有部分。如果有另一個查詢該值的進程,如果在刪除之後和插入之前查詢,它可能根本沒有任何值。 – Yexo 2011-04-13 06:23:23

+0

'INSERT ...在DUPLICATE KEY UPDATE上不執行任何刪除操作。 – zerkms 2011-04-13 06:48:22

1

您的建議意味着每次狀態更改總是有兩條指令。通常的做法是做一個UPDATE,然後檢查操作是否改變了任何行(大多數數據庫都有一個像ROWCOUNT這樣的變量,如果有變化,它應該大於0)。如果沒有,請執行INSERT。

搜索UPSERT爲尋找模式爲特定的DBMS

1

我個人認爲Update方法是最好的。不是首先執行SELECT來檢查記錄是否已經存在,您可以先嚐試更新,但如果沒有行受到影響(使用@@ ROWCOUNT),則可以執行INSERT。

原因是遲早你可能想要跟蹤狀態變化,最好的方法是使用狀態表上的觸發器保持所有變化的審計跟蹤。

4

既然你說的是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); 
+0

+1,出於某種原因,我只需要喜歡這個答案:) – 2011-04-13 06:57:33