【问题标题】:Update statement running for too long or not更新语句运行时间过长或没有
【发布时间】:2010-08-19 16:17:27
【问题描述】:

我不熟悉处理这么多数据(2000 万行),我不知道查询持续时间应该是什么:

update table set field = '1234'  

字段上没有索引。这个陈述用了 25 分钟。数据库设置为简单恢复。 25分钟似乎太长了?表有 9 列,小数据类型

【问题讨论】:

  • 服务器负载如何?您是否查看了 Profiler 以查看该盒子是否对 CPU 或内存征税?
  • 您要更新 2000 万行?请告诉我您的实际更新语句中有一个 where 子句。
  • @OMG Ponies:我们刚刚安装了 Windows Server 2008 R2,我查看了 sql server 进程,它使用了除了 28 MB 之外的所有 RAM。
  • 我不记得 Windows XP 允许 SQL Server 吃掉那么多内存
  • @Beth:不。在此查询中不需要也不需要 Where 子句。

标签: sql sql-server sql-server-2008


【解决方案1】:

如果您在一个事务中更新了 20M 行,那么您的时间完全取决于您的 IO 子系统:您拥有什么样的驱动器、什么样的磁盘文件布局等。如果您在 raid 10 中有 40 个轴和 4 个平衡文件和一个单独的类似电池用于日志然后结果令人担忧地缓慢。如果您使用单个 MDF 进行测试,该 MDF 与 LDF 在单个消费级质量 5000 转 HDD 上共享主轴,那么您的时间会非常快。

【讨论】:

  • +1:IO 是否始终是此类案例的问题,还是存在一个模糊的临界点?
  • 单个更新语句中的 20M 行都将取决于日志刷新的速度,当数据库检查点由于空闲页面的缓冲池压力而启动时会出现一些峰值。跨度>
  • 标志将是Avg. Disk Queue Length(每个主轴>2)和Avg. sec/transfer(>10ms)性能计数器。 msdn.microsoft.com/en-us/library/ms175903.aspx
  • @subt13:即使在简单模式下,事务也必须记录每一行更改,以便它可以进行回滚。 20M 行-> 20M 日志中的更改记录 + 为 20M 撤消操作保留的空间,它需要日志空间,并且每个位都必须写入磁盘。仅当您有多个事务时,恢复模型才会发挥作用,但无论恢复模型如何,它都不会使事情变得更快。对于某些 insert 操作,只有批量可能更快,而更新则永远不会。
【解决方案2】:
  • 是否有引用该字段的索引视图?
  • 该字段是否在(事务性)复制方案中发布?
  • 是否有其他会话在更新运行的同时访问该表?
  • 日志和数据文件是否存储在不同的磁盘上(物理磁盘,而不是同一硬件的两个不同分区)?
  • 是否存在引用该字段的检查约束?
  • 该表上是否有任何触发器?

所有这些以及可能的许多其他因素都会影响数据修改性能。

否则,请尝试使用 TOP 和仅查找未修改行的 WHERE 子句对更新进行批处理。

【讨论】:

  • 我尝试了批处理,但不确定批处理大小。我尝试了 10000 次,但需要的时间更长。
【解决方案3】:

您在大约 1500 秒内更新了 20 条 Mio 记录,平均每秒更新 7000 次。听起来很对。

【讨论】:

  • 因为数量级在我预期的范围内,小于 1000 会比 40000 还奇怪。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-22
  • 2015-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多