关于update语句的优化

jonics 2002-07-01 11:28:13
我有一张表的数据有100万以上,作update速度很慢,
比如我要把所有的记录某个字段全部置为0,不加任何条件!
执行一下update table set fieldname=0就要很长时间
该表有主键,有多个字段,除了主键没有其他索引
怎么样才能优化呢?
而且我在procedure里面和在sqlplus里单独执行相同的update语句,procedure里面慢得多,这又是怎么回事呢?

小弟初学数据库,希望大虾指点迷津!
...全文
231 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
blue__star 2002-07-11
  • 打赏
  • 举报
回复
将SGA设置为物理内存的1/2就可以
jonics 2002-07-11
  • 打赏
  • 举报
回复
fredrick:update table set fld=0只是我举了个简单的例子而已~~

chao_ping:同样的语句sqlplus和Procedure里面速度不同是那次我测试的时候正好碰到别人在进行大的数据库操作,我想是这个原因把!

icesummit:db_block_size = 4196,不知道是不是小了点?

感谢大家的帮助~~~~~
icesummit 2002-07-03
  • 打赏
  • 举报
回复
更新2500条记录要5秒应该是由于init.ora中db_block_size没有改动得缘故。
刚开始我的db_block_size=2048,更新2000条也要花5秒左右。
现在我重建了数据库,db_block_size=16384,更新10000条都没有5秒钟:)
看看你的db_block_size吧
icesummit 2002-07-03
  • 打赏
  • 举报
回复
更新2500条记录要5秒应该是由于init.ora中db_block_size没有改动得缘故。
刚开始我的db_block_size=2048,更新2000条也要花5秒左右。
现在我重建了数据库,db_block_size=16384,更新10000条都没有5秒钟:)
看看你的db_block_size吧
zhoubf725 2002-07-03
  • 打赏
  • 举报
回复
这样试试:
你可以先指定一个大的回滚段,然后在大表的外键建索引.


至于你说的存储过程速度居然比SQLPLUS慢,感觉不可思议.
麻烦把你的过程和sqlplus语句贴上吧.



fredrick 2002-07-03
  • 打赏
  • 举报
回复
首先你的数据库设计就有问题,有哪个人需要同时更新百万级的记录,而且更新的逻辑又那么简单,就死置个‘0’。update的语句其实是delete+insert两条语句实现的,就算是有索引它慢也是正常的,庆幸的是你的系统竟然能够扛住。如果逻辑简单你就不应该这么设计数据库,计算再来张表记录状态的变化也比这种处理效率高的不只万倍。
chao_ping 2002-07-03
  • 打赏
  • 举报
回复
乱扯!表是没法用dbms_keep来Keep的。 顶多alter table xxx cache;

至于你重建db_block_size, 呵呵,重构整个数据库哦?
而且重构DB_BLOCK_SIZE可以帮你提高这么多的速度,也难以接受。你确保别的条件都一样?

看看是不是log swich更不上。

这样全表Update的,有索引只会更加慢。我得意见。
在存储过程里面和SQLPlus里面的速度肯定是一样的。
比如给你一个实际测试的例子:
SQL> update usercare set care_date=sysdate
2
SQL> set timing on
SQL> /

386221 rows updated.

Elapsed: 00:00:37.98
SQL> rollback;

Rollback complete.

Elapsed: 00:00:23.23
SQL> create or replace procedure t as
2 begin
3 update usercare set care_date=sysdate;
4 end;
5 /

Procedure created.

Elapsed: 00:00:00.65
SQL> exec t

PL/SQL procedure successfully completed.

Elapsed: 00:00:35.16
SQL> rollback;

Rollback complete.

Elapsed: 00:00:23.29
bzszp 2002-07-01
  • 打赏
  • 举报
回复
楼上说的对,分段提交,如
declare
n number;
begin
n:=1;
delete from tb;
loop
update........
n:=n+1;
if mod(n,100)=0 then//每100条提交一次
commit;
end if;
exit when n=500000;//总次数
end loop;
end;
/
icesummit 2002-07-01
  • 打赏
  • 举报
回复
我想你还是应该每UPDATE 一定条数后,就commit 一次。我一般每2000条提交一次。写一个循环就OK了:)
向你100万的数据要是一次提交的话,回滚段会不够用的:)
jonics 2002-07-01
  • 打赏
  • 举报
回复
已经够大了呀~~~~~~
init.ora
---------------------
shared_pool_size = 102400000
shared_pool_reserved_size = 20000000
bzszp 2002-07-01
  • 打赏
  • 举报
回复
你执行update tbname set col='a';
这样很慢?
这样也慢的话增加init.ora中的share_pool_size参数
该参数是库高速缓存和数据字典的告诉缓存,该参数越大,将大大减少ORALCE进行重新分析语法的工作量和管理自身的时间。
3yugui 2002-07-01
  • 打赏
  • 举报
回复
还可以增加,DB_BLOCK_BUFFERS的数量。
如果此表经常使用可以把此表放到高速缓存中,ALTER TABLE AA CACHE;
3yugui 2002-07-01
  • 打赏
  • 举报
回复
可以把过程放到数据库缓冲区中,即固定。
可以用DBMS_SHARED_POOL.KEEP('SCOTT.AA','P');
3yugui 2002-07-01
  • 打赏
  • 举报
回复
还要考虑是不是存在行锁的现象。
xinpingf 2002-07-01
  • 打赏
  • 举报
回复
你这个字段上建有索引吗?这样也可能影响速度的
xinpingf 2002-07-01
  • 打赏
  • 举报
回复
不是倍数,会比倍数更长

回滚段很可能不够用
jonics 2002-07-01
  • 打赏
  • 举报
回复
小弟刚刚接触oralce,不知道怎么优化oracle 服务器!
服务器也不是由我维护的,我只是写程序时碰到了这个问题,速度太慢了!
我一个存储过程居然运行了半个小时~~
数据只有100万
KingSunSha 2002-07-01
  • 打赏
  • 举报
回复
更新2500条记录要5秒?你的服务器优化过吗?
简直是不可思议
jonics 2002-07-01
  • 打赏
  • 举报
回复
我测试了一下,更新2500条记录大概5秒~~~

我想知道如果更新一张100w记录的表所有记录,

update语句大概需要多少时间?

耗时是不是成倍数关系增长?

icesummit 2002-07-01
  • 打赏
  • 举报
回复
我觉得相同情况下应该是存储过程应该更快
加载更多回复(3)

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧