急,急,UPDATE执行时间过长。

zhangcyu 2004-08-11 06:26:14
UPDATE BILL.STAT_SERV_CONSUME_0406 A
SET CUST_ID = (SELECT CUST_ID FROM SUBSCRIBER B WHERE A.SERV_ID=B.SERV_ID)
WHERE A.SERV_ID is not null

这条语句执行10多个小时,还未执行完,
而同样的语句:
UPDATE BILL.STAT_SERV_CONSUME_0407 A
SET CUST_ID = (SELECT CUST_ID FROM SUBSCRIBER B WHERE A.SERV_ID=B.SERV_ID)
WHERE A.SERV_ID is not null
只要一分钟就可以搞定
STAT_SERV_CONSUME_0406和STAT_SERV_CONSUME_0407都是100多万条记录,表结构一样,索引一样:
-- Create table
create table STAT_SERV_CONSUME_0406
(
SERV_ID NUMBER,
CUST_ID VARCHAR2(12),
TICKET_TYPE VARCHAR2(4),
PAGE NUMBER,
DURATION NUMBER,
CHARGE NUMBER,
COUNTS NUMBER
)
tablespace TBS_BILL
pctfree 10
pctused 40
initrans 1
maxtrans 255
storage
(
initial 50M
minextents 1
maxextents unlimited
);
-- Create/Recreate indexes
create index IND_SERV_CMS_CST_ID_0406 on STAT_SERV_CONSUME_0406 (CUST_ID)
tablespace TBS_BILL
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 20M
minextents 1
maxextents unlimited
);
create index IND_SERV_CMS_SRV_ID_0406 on STAT_SERV_CONSUME_0406 (SERV_ID)
tablespace TBS_BILL
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 20M
minextents 1
maxextents unlimited
);
请问高手是何原因?

...全文
734 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
zgh2003 2004-08-13
  • 打赏
  • 举报
回复
UPDATE BILL.STAT_SERV_CONSUME_0406 A
SET CUST_ID = (SELECT CUST_ID FROM SUBSCRIBER B WHERE A.SERV_ID=B.SERV_ID)
WHERE A.SERV_ID is not null
中的“WHERE A.SERV_ID is not null”肯定会导致全表扫描,所以速度会变慢。

测试一下下面语句,看看能不能得到改善。
UPDATE BILL.STAT_SERV_CONSUME_0406 A
SET CUST_ID = (SELECT CUST_ID FROM SUBSCRIBER B WHERE A.SERV_ID=to_number(B.SERV_ID,999999));
当然这必须是在表SUBSCRIBER记录较少的前提下。

句中用到to_number函数,是因为你的表STAT_SERV_CONSUME_0406中的字段SERV_ID是NUMBER型,
而表SUBSCRIBER 中是SERV_ID VARCHAR2(11) not null,即字符型,
这也是导致慢的原因之一。

zhangcyu 2004-08-13
  • 打赏
  • 举报
回复
怎么指定一个大的回滚段
北极海hein 2004-08-13
  • 打赏
  • 举报
回复
试试在udate时开始事务指定一个大rollback segment看看.
sunjet2000 2004-08-12
  • 打赏
  • 举报
回复
我的解决办法:
我觉得建临时表应该能起到一定的作用!
建立临时表:
Create global temporary table temp1
as
(
SELECT CUST_ID, SERV_ID
FROM SUBSCRIBER B, STAT_SERV_CONSUME_0406 A
WHERE A.SERV_ID=B.SERV_ID
);
UPDATE BILL.STAT_SERV_CONSUME_0406 A
SET CUST_ID =
(
select * from temp1 C where A.SERV_ID = C.SERV_ID
)
WHERE A.SERV_ID is not null;
commit;
Create global temporary table temp2
as
(
SELECT CUST_ID, SERV_ID
FROM SUBSCRIBER B, STAT_SERV_CONSUME_0407 A
WHERE A.SERV_ID=B.SERV_ID
);
UPDATE BILL.STAT_SERV_CONSUME_0406 A
SET CUST_ID =
(
select * from temp1 C where A.SERV_ID = C.SERV_ID
)
WHERE A.SERV_ID is not null;
commit;
fieldsun 2004-08-12
  • 打赏
  • 举报
回复
SELECT COUNT(*) FROM BILL.STAT_SERV_CONSUME_0406 WHERE SERV_ID is not null
SELECT COUNT(*) FROM BILL.STAT_SERV_CONSUME_0407 WHERE SERV_ID is not null
这两个值是不是差别很大呀
tyrone98 2004-08-12
  • 打赏
  • 举报
回复
set autotrace on 看看两个更新的执行方式是否一样,可以先重新分析一下你的STAT_SERV_CONSUME_0407 表.
如果还是很慢
使用
update /*+ use_hash( a , b ) */指定为hash连接方式
jxc 2004-08-12
  • 打赏
  • 举报
回复
可以尝试两个语句多次,消除缓冲的影响后,看执行速度还有没有差别.
caven 2004-08-12
  • 打赏
  • 举报
回复
在运行INSERT, DELETE 和 UPDATE 语句前最好估算一下可能操作的记录范围,
应该把它限定在较小 (一万条记录) 范围内,. 否则ORACLE处理这个事物用到很大的回退段.
程序响应慢甚至失去响应. 如果记录数上十万以上这些操作, 可以把这些SQL语句分段分次完成, 其间加上COMMIT 确认事物处理
zhangcyu 2004-08-12
  • 打赏
  • 举报
回复
我测试过,和缓冲没有关系,不敢哪个语句先运行,0406都要执行很久
另外各位提出增加主键和唯一索引的办法也行不通,因为我们这个系统是针对全省电信的一个系统,各个地市版本要一样
baojianjun 2004-08-11
  • 打赏
  • 举报
回复
那就是wylwyl1130(落雪山林)所說的原因了
zhangcyu 2004-08-11
  • 打赏
  • 举报
回复
运行结果和前者基本类似
baojianjun 2004-08-11
  • 打赏
  • 举报
回复
不好意思,是要看這個的結果
SELECT COUNT(*) FROM BILL.STAT_SERV_CONSUME_0406 WHERE SERV_ID is not null
SELECT COUNT(*) FROM BILL.STAT_SERV_CONSUME_0407 WHERE SERV_ID is not null
zhangcyu 2004-08-11
  • 打赏
  • 举报
回复
SELECT COUNT(*) FROM BILL.STAT_SERV_CONSUME_0406
SELECT COUNT(*) FROM BILL.STAT_SERV_CONSUME_0407

两个表都是180万条记录,用时都是1秒左右
baojianjun 2004-08-11
  • 打赏
  • 举报
回复
SELECT COUNT(*) FROM BILL.STAT_SERV_CONSUME_0406
SELECT COUNT(*) FROM BILL.STAT_SERV_CONSUME_0407
這兩句的結果是什麼?
zhangcyu 2004-08-11
  • 打赏
  • 举报
回复
0407也没有主键
wylwyl1130 2004-08-11
  • 打赏
  • 举报
回复
你创建一个主健或者一个唯一索引吧
update操作比较占用回滚段

第二个表执行快的原因是在第一个表的基础上
SELECT CUST_ID FROM SUBSCRIBER B WHERE A.SERV_ID=B.SERV_ID内容还在缓冲区
baojianjun 2004-08-11
  • 打赏
  • 举报
回复
樓主嘗試一下以下語句:
SELECT COUNT(*) FROM BILL.STAT_SERV_CONSUME_0406
SELECT COUNT(*) FROM BILL.STAT_SERV_CONSUME_0407
上面兩個查詢語句的結果是什麼,各花多少時間?

還有就是主鍵的問題,我看0406中沒有主鍵,0407中有嗎?
zhangcyu 2004-08-11
  • 打赏
  • 举报
回复
SUBSCRIBER表结构和主键见下,stat_serv_consume_0406没有主键:
- Create table
create table BASEDBA.SUBSCRIBER
(
SUBS_ID VARCHAR2(11) not null,
SEQ NUMBER(3) not null,
SUBS_CODE VARCHAR2(16),
CUST_ID VARCHAR2(11) not null,
SERV_ID VARCHAR2(11) not null,
CREDIT_GRADE_ID VARCHAR2(5),
AREA_ID VARCHAR2(8),
CREA_DATE DATE not null,
STATE CHAR(1) not null,
MODI_DATE DATE not null
)
tablespace TBS_SERV
pctfree 10
initrans 3
maxtrans 255
storage
(
initial 128K
minextents 1
maxextents unlimited
);
-- Create/Recreate primary, unique and foreign key constraints
alter table BASEDBA.SUBSCRIBER
add constraint PK_SUBSCRIBER primary key (SUBS_ID,SEQ)
using index
tablespace TBS_SERV_IDX
pctfree 10
initrans 3
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
alter table BASEDBA.SUBSCRIBER
add constraint AK_AK_SUBSCRIBER_SUBSCRIB unique (CUST_ID,SERV_ID)
disable;
alter table BASEDBA.SUBSCRIBER
add constraint FK_SUBSCRIB_REFERENCE_SERV foreign key (SERV_ID)
references BASEDBA.SERV (SERV_ID);
-- Create/Recreate indexes
create index BASEDBA.IDX_SUBSCRIBER_CUST_ID on BASEDBA.SUBSCRIBER (CUST_ID)
tablespace TBS_SERV_IDX
pctfree 10
initrans 3
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
create index BASEDBA.IDX_SUBSCRIBER_SERV_ID on BASEDBA.SUBSCRIBER (SERV_ID)
tablespace TBS_SERV_IDX
pctfree 10
initrans 3
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
-- Grant/Revoke object privileges
grant select, insert, update, delete on BASEDBA.SUBSCRIBER to BILL;
grant select, insert, update, delete, references, alter, index on BASEDBA.SUBSCRIBER to PUBLIC;
jxc 2004-08-11
  • 打赏
  • 举报
回复
这两个表都没有主键吗?
zhangcyu 2004-08-11
  • 打赏
  • 举报
回复
SUBSCRIBER.SERV_ID上已经有索引了
加载更多回复(1)
酷窗版演示:http://www.edd8.com/bbs/index.asp?style=0 简装版演示:http://www.edd8.com/bbs/index2.asp 一点点论坛(http://www.edd8.com/bbs)使用说明 欢迎大家下载使用一点点论坛,在使用论坛前,请认真阅读以下内容: ===================================== 论坛:一点点论坛(http://www.edd8.com/bbs) 主页:一点点星空驿站(http://www.edd8.com/) 站长:叮咚虫(e_Mail:b_li@163.com) 版本:EDD8 Ver.2003 for DV =====================================   一点点论坛是建立在动网论坛基础上的ASP互动论坛,从动网Var5.b109开始论坛结构便开始脱离动网,与动网升级一起,本论坛本身也同时实现了动网新的功能,到519的发布,本人常得论坛本身已功能基本完善,所以决定与动网完全脱离,到动网Final的出现,本论坛也决定不再跟随动网升级了,本人全面对原来的论坛进行了代码优化和版面重排,并升级了部分功能代码,完成了现在这样的论坛。使论坛已经完全脱离了动网,以后也不可以随动网一起升级了!   所以选择本论坛的朋友请先明白,如果采用了本论坛的数据结构,以后就不可以和动网一起升级了,而现有的动网Final版的数据库和本论坛的数据库也是不兼容的!对于动网V5.b519的用户,本人同时在压缩包里提供了升级文件,可以把你519的数据库升级成和本论坛一致的数据结构!   由于一些朋友催得较,部分功能还是没有完善的(但不会出错),我以后也会给出升级包的。所以决定使用本论坛的朋友,请一定要到本站论坛的“站务办公室”进行指定的留言签名,以好我第一时间通知大家升级!   论坛中使用到的部分插件并没有一同奉上,原因是我还没完成代码优化,请过几天到我的论坛上下载。可以下载的插件主要有:社区银行、网络拳皇、可乐吧台球、五子棋等等…… ===================================== 主要特色功能说明: ◎ 双版面设计,用户可以根据不同爱好选择不同的版式(酷窗版和精简版),系统会记录用户的选择,不用重复选择,也不会出现版面混淆等现象; ◎ 发贴回贴互动功能,给用户随机的互动事件,增加用户的参与兴趣; ◎ 增强的UBB代码和JS代码,新增的买卖贴、定时贴等十几种特色功能UBB代码; ◎ 贴子功能加强,增加互动鲜花、鸡蛋、金钱、炸弹等功能,并保存数据作为用户在论坛的人缘依据; ◎ 不好说了,等你去发掘吧,不然又说我叫卖了…… ====================================== 安装说明: 解压就可以了,数据库名称和路径有变动时不要忘了在CONN。ASP中进行相应修改。 (注意:当论坛中一个贴子也没有时,论坛明星会出错,但当你加入贴子后就正常了,大家不要惊慌) 升级:(对519),解压后把你的原519数据库覆盖现数据库,再执行根目录下的UPDATE。ASP文件就行了,如果没有升级成功的提示,说明你的数据不能进行升级! (注意:数据库的升级应做了备份,并在本机上进行!) ====================================== 最后一点说明: 由于论坛本来是打算自己用的,所以在设计的过程中部分变量已经去掉,不能从后台设置了(如表格边框),请大家最好保持现有的风格。 如果还不问题,可以到我的论坛上来交流。??注意,由于本人时间不限,技术支持是有限的,请不要过于强求!

17,377

社区成员

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

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