SQL Server中Upsert的三種方式


本文介紹了SQL Server中Upsert的三種常見寫法以及他們的性能比較。

SQL Server並不支持原生的Upsert語句,通常使用組合語句實現upsert功能。

 

假設有表table_A,各字段如下所示:

int型Id為主鍵。

 

方法1:先查詢,根據查詢結果判斷使用insert或者update

IF EXISTS (SELECT 1 FROM table_A WHERE Id = @Id)
    BEGIN
        UPDATE dbo.table_A
        SET Value = @Value
        WHERE Id = @Id;
    END
ELSE
    BEGIN
        INSERT INTO dbo.table_A (Id, Value)
        VALUES(@Id, @Value)
    END

 

方法2:先更新,根據更新結果影響的條目數判斷是否需要插入

UPDATE dbo.table_A
SET Value = @Value
WHERE Id = @Id;
    
IF(@@ROWCOUNT = 0)
BEGIN
    INSERT INTO dbo.table_A (Id, Value)
    VALUES(@Id, @Value)
END

 

方法3:使用MERGE語句,將待upsert的數據作為source,merge到目標表 

MERGE INTO table_A as T
USING (SELECT @Id AS id, @Value AS value ) AS S
ON T.Id = S.id
WHEN MATCHED THEN
    UPDATE SET T.Value = S.value
WHEN NOT MATCHED THEN
    INSERT(Id, Value) VALUES(S.id, S.value);

 

性能比較

在50萬行數據項中隨機upsert10萬次

 

場景一:upsert數據項100%命中update

 

場景二:upsert數據項100%命中insert

 

場景三:upsert數據項Id為隨機數,~50%insert,~50%update

 

從圖中可以看出實驗數據存在部分偏差,大體上這三種方法在性能上的差別非常小。對於絕大多數upsert並非關鍵路徑的程序,方法2在可讀性和執行性能上綜合來講是較優的方案。

在對性能苛求的場景,可以選用MERGE語句,以下是MERGE語句的優點:”

  1. Faster performance. The Engine needs to parse, compile, and execute only one query instead of three (and no temporary variable to hold the key).
  2. Neater and simpler T-SQL code (after you get proficient in MERGE).
  3. No need for explicit BEGIN TRANSACTION/COMMIT. MERGE is a single statement and is executed in one implicit transaction.
  4. Greater functionality. MERGE can delete rows that are not matched by source (SRC table above). For example, we can delete row 1 from A_Table because its Data column does not match Search_Col in the SRC table. There is also a way to return inserted/deleted values using the OUTPUT clause.“

引用:http://www.sergeyv.com/blog/archive/2010/09/10/sql-server-upsert-equivalent.aspx


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM