【问题标题】:Why does an UPDATE take much longer than a SELECT?为什么 UPDATE 比 SELECT 需要更长的时间?
【发布时间】:2010-01-05 22:36:45
【问题描述】:

我有以下几乎立即完成的选择语句。

declare @weekending varchar(6)  
set @weekending = 100103

select InvoicesCharges.orderaccnumber, Accountnumbersorders.accountnumber  
from Accountnumbersorders, storeinformation, routeselecttable,InvoicesCharges, invoice   
where InvoicesCharges.pubid = Accountnumbersorders.publication  
and Accountnumbersorders.actype = 0  
and Accountnumbersorders.valuezone = 'none'  
and storeinformation.storeroutename = routeselecttable.istoreroutenumber   
and storeinformation.storenumber = invoice.store_number  
and InvoicesCharges.invoice_number = invoice.invoice_number  
and convert(varchar(6),Invoice.bill_to,12) = @weekending  

但是,等效的更新语句需要 1m40s

declare @weekending varchar(6)
set @weekending = 100103
update InvoicesCharges  
set InvoicesCharges.orderaccnumber = Accountnumbersorders.accountnumber  
from Accountnumbersorders, storeinformation, routeselecttable,InvoicesCharges, invoice   
where InvoicesCharges.pubid = Accountnumbersorders.publication  
and Accountnumbersorders.actype = 0  
and dbo.Accountnumbersorders.valuezone = 'none'  
and storeinformation.storeroutename = routeselecttable.istoreroutenumber 
and storeinformation.storenumber = invoice.store_number 
and InvoicesCharges.invoice_number = invoice.invoice_number
and convert(varchar(6),Invoice.bill_to,12) = @weekending

即使我添加:

and InvoicesCharges.orderaccnumber <> Accountnumbersorders.accountnumber

在更新语句的末尾将写入次数减少到零,它需要相同的时间。

我在这里做错了吗?为什么会有这么大的差异?

【问题讨论】:

  • 额外的AND子句仍然是个好主意,为什么只需要更新2行就更新50,000行?

标签: sql-server performance sql-server-2005 tsql triggers


【解决方案1】:
  • 事务日志文件写入
  • 索引更新
  • 外键查找
  • 外键级联
  • 索引视图
  • 计算列
  • 检查约束
  • 闩锁
  • 锁升级
  • 快照隔离
  • 数据库镜像
  • 文件增长
  • 其他进程读/写
  • 页面拆分/不合适的聚集索引
  • 前向指针/行溢出事件
  • 索引不佳
  • 统计数据已过期
  • 糟糕的磁盘布局(例如,一个大 RAID 用于所有内容)
  • 使用具有表访问权限的 UDF 检查约束
  • ...

虽然,通常的嫌疑人是触发器...

另外,你的额外条件没有意义:SQL Server 怎么知道忽略它?大多数行李仍然会生成更新......即使触发器仍然会触发。例如,在搜索其他条件的行时必须持有锁

在 2011 年 9 月和 2012 年 2 月编辑,提供更多选项

【讨论】:

  • 是的,原因是触发器。我是新手,“代码”不是我的。感谢您的提醒。我添加了额外的条件,因为我认为写入磁盘可能需要很长时间,所以没有不必要的磁盘写入。再次,非常感谢。
  • 尤其是“设计”的触发器,用于在所有行中游标,而不是以基于集合的方式运行!
【解决方案2】:

更新必须锁定和修改表中的数据,并将更改记录到事务日志中。选择不必做任何这些事情。

【讨论】:

  • Nitpick:您可以在 SELECT 语句中使用 DML,只是没有写回...除非它是 INSERT INTO ... SELECT...
  • 并且还修改表上的任何索引。索引越多,写入的时间越长。
  • 那为什么即使有额外条件也需要很长时间?应该对表格进行零更改,但仍然需要很长时间。
【解决方案3】:

因为阅读不会影响索引、触发器以及你有什么?

【讨论】:

    【解决方案4】:

    在慢速服务器或大型数据库中,我通常使用 UPDATE DELAYED,它等待“中断”来更新数据库本身。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 2021-03-19
      • 1970-01-01
      • 2017-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多