更快地插入新记录或更新预加载的表

时间:2017-05-07 17:12:58

标签: tsql transactions insert try-catch

我有一个MS SQL表,其复合主键有两个整数值,另一个字段表示与该记录关联的会话。我们将这些PK称为“位置”和“项目”,并将相关值称为“购物者”。每个位置都有1000多个项目,每个项目只能由一位购物者选择。

在购物者提出请求时,我尝试使用位置,项目和购物者插入该表格。我返回的结果是基于插入是否抛出主键错误。

为了让您了解音量,可能有200名购物者在一个地点争夺1000件商品。每个购物者可以每1.5秒左右发出一次请求。我任何时候都有大约10个繁忙的地方。当具有位置/项目的表格中只有不到100万条记录时。

所以,我的问题是:

  1. 是否可以尝试插入然后捕获抛出的错误(正如我现在所做的那样),或者使用事务是否更好然后在插入之前存在?
  2. INSERT示例

    BEGIN TRY  
      INSERT INTO table
      (
          location
        , item
        , shopper
      )
      VALUES
      (
          @location
        , @item
        , @shopper
      )
    END TRY  
    BEGIN CATCH  
      -- The insert failed, which means that another shopper
      -- has already claimed this item. Respond accordingly
    END CATCH 
    

    带有EXISTS / INSERT的示例

      BEGIN TRANSACTION
        IF NOT EXISTS (
          SELECT 1 
          FROM table 
          WHERE location = @location
            AND item = @item
        )
        INSERT INTO table
        (
            location
          , item
          , shopper
        )
        VALUES
        (
            @location
          , @item
          , @shopper
        )
        ELSE
        BEGIN
          -- "Insert" was not successful, handle appropriately
        END
      COMMIT TRANSACTION
    
    1. 为每个项目创建空记录然后进行更新(使用适当的WHERE子句以确保其他购物者不会被碰撞)会更快吗?在这种情况下,我确信必须进行后续读取以查看更新是否成功。
    2. 实施例

      UPDATE table
      SET shopper = @shopper
      WHERE location = @location
        AND item = @item
        AND shopper IS NULL
      
      -- Check to see if the update was successful
      
      IF @shopper = (SELECT shopper 
                     FROM table
                     WHERE location = @location
                       AND item = @item)
      BEGIN
        -- Assignment is successful
      END
      ELSE
      BEGIN
        -- Assignment was unsuccessful
      END
      

      我的理解是UPDATES确实没有INSERTS那么快,因为它们都创建了一个新行。在UPDATE的情况下,它只标记要删除的原始行。

      1. 我应该将系统的这一部分移动到像REDIS这样的东西吗?散列平台真的可以提供大幅提升的性能吗?
      2. 感谢您的反馈!

0 个答案:

没有答案