哪个SQL Update更快/更高效

时间:2014-09-04 08:04:17

标签: sql sql-server

每次采取某项行动时,我都需要更新一个表格。

MemberTable

  • Name varchar 60
  • Phone varchar 20
  • Title varchar 20
  • Credits int< - 需要不断更新的
  • 等所有相关成员列10 - 15总计

我应该用以下内容更新此表:

UPDATE Members 
SET Credits = Credits - 1 
WHERE Id = 1

或者我应该创建另一个名为account的表,只有两列,如:

帐户表

  • Id int
  • MemberId int< - 成员表的外键
  • Credits int

并使用以下内容进行更新:

UPDATE Accounts 
SET Credits = Credits - 1 
WHERE MemberId = 1

哪一个更快更有效?

我已经读过SQL Server必须读取整行才能更新它。我不确定这是不是真的。任何帮助将不胜感激

3 个答案:

答案 0 :(得分:1)

实际上后面的方式会更快。 如果您的数字交易非常庞大,那么毫秒精度非常重要,这样做会更好。
或者也许有些成员没有学分,你也可以节省一些空间。

但是,如果不是,那么保持表结构规范化是件好事。如果每个帐户始终都有credit,最好将其作为表Member中的列添加。
尽量不要使用不必要的中间表,这会占用更多空间(包括所有这些外键和附加ID)。此外,它还使您的架构更复杂。

最后,这取决于您的要求。

答案 1 :(得分:1)

我知道这并没有直接回答这个问题,但我会把它作为替代解决方案。

您是否对历史交易感到困扰?不是每个人都会,但如果你或其他未来的读者,这就是我将如何处理这个问题:

CREATE TABLE credit_transactions (
   member_id        int      NOT NULL
 , transaction_date datetime NOT NULL
   CONSTRAINT df_credit_transactions_date DEFAULT Current_Timestamp
 , credit_amount    int      NOT NULL
 , CONSTRAINT pk_credit_transactions PRIMARY KEY (member_id, transaction_date)
 , CONSTRAINT fk_credit_transactions_member_id FOREIGN KEY (member_id)
     REFERENCES member (id)
 , CONSTRAINT ck_credit_transaction_amount_not_zero CHECK (credit_amount <> 0)
);

就写作表现而言......

INSERT INTO credit_transactions (member_id, credit_amount)
  VALUES (937, -1)
;

很简单,呃!不需要行锁。

这种方法的缺点是,要计算成员“余额”,你必须进行一些计算。

CREATE VIEW member_credit
  AS
SELECT member_id
     , Sum(credit) As credit_balance
     , Max(transaction_date) As latest_transaction
FROM   credit_transactions
GROUP
    BY member_id
;

然而,使用视图可以使事情变得美观和简单,并且可以进行适当的优化。

哎呀,您可能想在该视图上输入NOLOCK(在做出决定之前阅读此内容)以减少锁定影响。

TL; DR:

优点:快速写入速度,可用的交易记录

缺点:读取速度较慢

答案 2 :(得分:0)

由于ID是主键,所有dbms必须做的是查找索引中的键,获取记录并进行更新。应该没有太大的性能问题。

使用帐户表可以获得完全相同的访问方法。但你是对的;由于每条记录的数据较少,您可能更经常在内存缓存中拥有该记录,从而节省了物理读取。但是,我不希望这种情况经常发生。好吧,您可能更多地使用您的成员表而不是帐户表。这使得成员记录更有可能已经存在于缓存中,因此反之亦然,因此您的帐户表访问速度较慢。

缓存访问与物理读取是唯一的区别,因为使用主键,您将以与ID索引相同的方式行走,而不是直接访问一个特定记录。

我不建议使用帐户表。它有点模糊了数据结构,两个表之间的关系为1:1,可能无法被其他用户识别。你不可能从中获得太多收益。 (如上所述,你甚至可能会失去表现。)