簡體   English   中英

插入失敗,然后更新或加載,然后確定是插入還是更新

[英]Insert fail then update OR Load and then decide if insert or update

我在Java中有一個Web服務,它接收要在數據庫中插入或更新的信息列表。 我不知道要插入或更新哪個。

哪一種是獲得更好性能結果的最佳方法:

  1. 遍歷列表(一個對象列表,上面有表pk),嘗試在數據庫中插入該條目。 如果插入失敗,請運行更新

  2. 嘗試從數據庫加載條目。 如果檢索到的結果更新,則不插入該條目。

  3. 另外一個選項? 告訴我怎么回事兒 :)

在初次通話中,我認為大多數條目將是新的bd條目,但是會有一個飽和點,大多數條目將要更新。

我說的是一個數據庫表,它可以以成熟的形式覆蓋超過1億個條目。

你會怎么做? 性能是我最重要的目標。

如果您的數據庫支持MERGE,我會認為這是最有效的(並將所有數據視為一個集合)。

看到:

http://www.oracle.com/technology/products/oracle9i/daily/Aug24.html

https://web.archive.org/web/1/http://blogs.techrepublic%2ecom%2ecom/datacenter/?p=194

如果性能是您的目標,那么首先要擺脫單詞迭代這個詞! 學會按組做事。

如果需要更新或插入,請始終先進行更新。 否則,很容易發現自己意外地更新了剛剛插入的記錄。 如果執行此操作,則可以使用標識符來查看記錄是否存在。 如果標識符存在,則進行更新,否則進行插入。

重要的是要了解收到的列表中插入數量與更新數量之間的平衡或比率。 恕我直言,您應該實施一個抽象策略,說“在數據庫上堅持”。 然后創建具體的策略,例如:

  1. 檢查主鍵,如果找到零條記錄,則插入,否則更新
  2. 是否進行更新,如果失敗,則進行插入。
  3. 其他

然后從配置文件中提取要使用的策略(例如,類的完全限定名稱)。 這樣,您可以輕松地從一種策略切換到另一種策略。 如果可行,可能取決於您的域,您可以進行試探,以根據集合上的輸入實體選擇最佳策略。

MySQL支持此功能:

INSERT INTO foo
SET bar='baz', howmanybars=1
ON DUPLICATE KEY UPDATE howmanybars=howmanybars+1

選項2不會是最有效的。 當您執行實際的插入或更新操作以執行主鍵時,數據庫將為您進行此檢查。 通過自己進行此檢查,您將產生兩倍於表查找的開銷,以及Java代碼的額外往返路程。 選擇最可能的情況並樂觀地進行編碼。

在選項1上展開,您可以使用存儲過程來處理插入/更新。 這個使用PostgreSQL語法的示例假定插入是正常情況。

CREATE FUNCTION insert_or_update(_id INTEGER, _col1 INTEGER) RETURNS void
AS $$
    BEGIN
        INSERT INTO
            my_table (id, col1)
        SELECT
            _id, _col1;
    EXCEPTION WHEN unique_violation THEN
        UPDATE
            my_table
        SET
            col1 = _col1
        WHERE
            id = _id;
    END;
END;
$$
LANGUAGE plpgsql;

您也可以使更新正常,然后檢查受update語句影響的行數,以確定該行是否實際上是新行,並且需要執行插入操作。

正如在其他答案中提到的那樣,處理此操作的最有效方法是分批處理:

  1. 獲取傳遞到Web服務的所有行,並將它們批量插入到臨時表中
  2. 從臨時表更新主表中的行
  3. 從臨時表的主表中插入新行
  4. 處置臨時表

要使用的臨時表的類型以及最有效的管理方式取決於您使用的數據庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM