在SQL Server中不断更新同一行是不是很糟糕?

时间:2011-03-29 20:39:44

标签: sql-server database-design

我正在使用SQL Server存储有关每个用户的几条信息。某些项目(例如用户名/密码)很少会改变,但其他项目每隔几秒就会改变一次(例如经度/纬度)。

我希望这个系统能够在一天的大部分时间内被一些有用的用户使用。所以 每个用户每天更新10,000次到此表。

将不断变化的信息和大多数静态信息存储在同一行中是不是存在缺点?我应该将静态信息保存在一个表中,并更改另一个表中的信息吗?

6 个答案:

答案 0 :(得分:3)

您可以将所有信息保存在一个表中,只要它在逻辑上属于一个表。您可能会以这种方式锁定用户行,但乐观锁定应该在大多数情况下都能正常工作。

但是,您应该只更新更新的字段。如果您对表上的不同数据项有这样的单独需求,您应该编写专门的数据访问更新例程。

好处是您只需要从数据库传输所需的数据,这将减少网络,客户端和数据库的延迟和负载。

答案 1 :(得分:3)

当更新和登录同时发生时,在当前解决方案中进行扩展时可能会出现问题。如果您使用草率的SELECT *语句,登录的性能可能会降低,甚至可能会面临锁定。

如果从多个来源更新纬度/经度是完全动态的,那么您一定要考虑将其存储在新表中,甚至可能为每次更新创建一个新行。如果多个源不断更新同一行,您肯定会遇到性能/锁定问题。创建一个新行似乎违反直觉,但它允许您几乎同时从多个源中导入数据并使用时间戳或类似方法查询该数据以查找最新更新,同时仍然保持更新查询非常精简和快速。通过时间戳可以自动且快速地进行修剪。

答案 2 :(得分:1)

如果您继续使用当前值覆盖LAT / LON,则会丢失可能有价值/有用的数据。我想,更好的是,只需在PersonLocation表中插入一个新行:

       id  autoincrementing integer
       personid  int  fk references persons(id)  [indexed non-unique to speed queries on person location history)
       lat   float
       lon   float
       asof  datetime  default getdate()

编辑:如果您需要经常获取当前位置,可以在(personid,datetime)上考虑复合索引。

答案 3 :(得分:0)

根据访问此数据库的应用程序的使用情况,如果您打算经常更新该单个记录,则可能会遇到锁定问题。此外,出于理智,维护和可扩展性的考虑,您可能希望查看normalization

答案 4 :(得分:0)

如果您更新的列是集群索引的一部分(假设存在一个),那么您将为SQL服务器带来相当多的开销,因为它重新排列表/索引结构以维护集群序列。如果它们是非聚集索引的一部分,则会产生维护索引结构的开销。

在这两种情况下,统计数据也会发挥作用。您的统计信息可能会过时,从而导致查询/存储过程提出次优执行计划:您可能会比其他情况更频繁地运行更新统计信息。

由于数据行的大小不会更改,因此应该更新未参与索引的固定长度列。更新不参与索引的可变长度或可空列可能会导致页面拆分,因为数据行的长度会发生变化(更不用说页面拆分导致的索引维护开销)。

答案 5 :(得分:0)

每天10,000次更新不是您将不必担心的事情。每分钟10,000次更新可能会成为一个问题。为数据库建模以保持简单,并且出于性能原因,不要试图模仿该模型。 Oded关于仅更新正在更改的列的建议是合理的,无论您的更新量是多少,因为您仍然希望尊重带宽,无论您更新的频率如何。