为什么UPDATE需要比SELECT更长的时间?

时间:2010-01-05 22:36:45

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

我有以下select语句几乎立即完成。

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

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

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

4 个答案:

答案 0 :(得分:22)

  • 事务日志文件写入
  • 索引更新
  • 外键查找
  • 外键级联
  • 索引视图
  • 计算列
  • 检查约束
  • 锁存器
  • 锁定升级
  • 快照隔离
  • 数据库镜像
  • 文件增长
  • 读/写其他流程
  • 页面拆分/不合适的聚集索引
  • 转发指针/行溢出事件
  • 糟糕的指数
  • 统计数据过时
  • 糟糕的磁盘布局(例如,所有东西都有一个大的RAID)
  • 使用具有表访问权限的UDF检查约束
  • ...

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

另外,你的条件额外没有意义:SQL Server如何知道忽略它?大部分行李仍然会产生更新......即使触发器仍然会触发。在搜索行以查找其他条件时必须保持锁定,例如

2011年9月和2012年2月编辑了更多选项

答案 1 :(得分:6)

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

答案 2 :(得分:1)

因为阅读不会影响指数,触发器,还有什么?

答案 3 :(得分:1)

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