一个有关SQL的update问题,为什么这么慢?(50分)

  • 主题发起人 主题发起人 老莫
  • 开始时间 开始时间

老莫

Unregistered / Unconfirmed
GUEST, unregistred user!
SQL SERVER6.5
有两个表,用其中一个表(4000条记录)的日期字段,去更新另一个表(200000条记录)里的相同字段。
用一个‘bh’字段链接,两个个表对‘bh’都做了index
update yhb set rq=temp.rq from temp where yhb.bh=temp.bh
这条语句执行得非常慢,用了将近半个小时
为什么?
 
我用下列写法 .
update yhb set rq=temp.rq where exists( select * from temp where yhb.bh=temp.bh)

最好看一下你究竟更新了多少条记录, 半个小时算快的.
因为Server要启动 事物处理, 锁定被更新的记录. 200000刚刚好可以被完全
更新, 超过一定的更新记录数, 事物还会被回滚, 我曾经传送1000000条记录
到另一个库, 结果是等了1个小时后, 出错了, 一看, 记录锁的数目不够了,
只传送了200000多条, 之后系统又花了半个多小时回滚系统 . 200000多条
也泡汤了 , 后来我只好每100000为一组, 共12组进行批量Insert表. 这才搞定.

最后, 好累的说.

 
SQL Server的速度无法和文件型数据库的相比,同样的操作在Foxpro下可能是
一眨眼的事,不过数据库的完整性和安全性,Foxpro就上不了台面.有得必有失么.
 
update yhb set rq=tmprq where exists( select rq as tmprq from temp where yhb.bh=temp.bh)
应该会快一些吧。
 
其实我只更新了4000条记录,会不会是索引上的问题呢?
 
你最好用簇式的唯一索引 .
 
其实temp表里的bh在yhb里都存在,总共更新4000条记录
update yhb set rq=temp.rq from temp where yhb.bh=temp.bh

update yhb set rq=temp.rq where exists( select * from temp where yhb.bh=temp.bh)
有什么区别么?不好意思,我现在不能实验,另外对sql不是很熟,各位大侠能不能
说的细一点。

 
200000条记录近半个小时不算慢了对于SQL Server,
你可以把数据库设置为Single User,会快一点.
 
虽然你只更新了4000条记录,但sql server 需要扫描200000条记录.
这种语句可以用一个存储过程实现:
对只有4000条的表进行循环,修改另外一个表中的数据。
被修改表中应该有一连接字段建立的索引.聚簇索引在此最好
不药用,若建立了聚簇索引,插入一条记录就会变的很慢。
 
anzhiping: 聚簇索引恰恰可以提高Update 的效率, 但是数据表都应该有
唯一索引(数据库设计法则). 所以Insert时都需要唯一主键的判别, 这时
簇式索引仍然是最快的 , 当较大量的批量移动添加时, 在保证主键不会被
重复时, 可以先删除目标表的全部索引, 当批量操作完后, 再重建索引.
 
此类处理,我也遇到过,不过是在ORACLE,由于大规模事务需要很大的ROLLBACK段,
REDOLOG等资源,再加上LOCK占用,SQL语法,INDEX设置已经不是主要问题.
最好:采用分段处理,每次更新一条或若干条.当然这需要编写过程.
事务最好也分几次提交.当然即使在一个事务中提交,速度也会加快,应为ROLLBACK段
等资源申请会被分成很多次,而不是一次.

 
其一是用stored procedure可以明显地提高速度.
其二是检查你的两张表之间是否还有其他限制条件.
 
1.使用存储过程.
2.拆分成数个事务.
3.进行Prepare预处理.
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
540
import
I
I
回复
0
查看
551
import
I
I
回复
0
查看
493
import
I
后退
顶部