免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: jack9981
打印 上一主题 下一主题

我这条语句跑了5个半小时啊,高手帮忙优化一下。 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2007-09-10 16:31 |只看该作者
org表的结构是这样的( old_acct, ..., old_acct1, old_acct2...)
这几个字段都需要进行转换。
old_acct是主键, 几个字段的值域范围一样, 但是同一条记录中,各个字段的取值却是没有关系。

可以使用临时表

论坛徽章:
0
12 [报告]
发表于 2007-09-10 16:33 |只看该作者
原帖由 jack9981 于 2007-9-10 16:31 发表
org表的结构是这样的( old_acct, ..., old_acct1, old_acct2...)
这几个字段都需要进行转换。
old_acct是主键, 几个字段的值域范围一样, 但是同一条记录中,各个字段的取值却是没有关系。

可以使用临时表


前面你不是说org.old_acct不是主键?
这个SQL执行是日常执行,还是偶尔手工执行一次。执行频率如何。

[ 本帖最后由 numenhuang 于 2007-9-10 16:37 编辑 ]

论坛徽章:
0
13 [报告]
发表于 2007-09-10 17:06 |只看该作者
原帖由 numenhuang 于 2007-9-10 16:33 发表


前面你不是说org.old_acct不是主键?
这个SQL执行是日常执行,还是偶尔手工执行一次。执行频率如何。

执行old_acct1, old_acct2转换的时候,就不是主键了啊,我只是说了通用的处理模式。
这个作业只要执行一次就好了。不过总的作业时间不能超过10个小时。现在一张表都是几个字段需要转换,时间不够啊。
而且现在只是测试的2000万条记录,最大的表有4000万条记录。

论坛徽章:
0
14 [报告]
发表于 2007-09-10 17:09 |只看该作者
org表的结构是这样的( old_acct, ..., old_acct1, old_acct2...)
old_acct是主键

old_acctx需要转换

转换数据来自
chg old_acct?都是这个字段,有索引?

论坛徽章:
0
15 [报告]
发表于 2007-09-10 17:29 |只看该作者
比如要更新org.old_acct1,无索引字段
1. 创建临时表 t

2. insert into t select org.old_acct,chg.new_acct,chg_acct1 from org,chg where chg.old_acct1 = org.old_acct
不知道你数据库版本和优化器是什么

3.update org ta set old_acct1=(select new_acct from t where ta.old_acct = t.old_acct)
where exists( select 'X' from t where ta.old_acct = t.old_acct)
可以在临时表上old_acct创建索引。

招聘 : Linux运维
论坛徽章:
0
16 [报告]
发表于 2007-09-10 18:00 |只看该作者
原帖由 jack9981 于 2007-9-10 14:23 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7330409&ptid=988771]
update org set org.old_acct = (select chg.new_acct from chg where chg.old_acct = org.old_acct )
where org.old_acct in ( select old_acct  from chg )   


逻辑上有问题,

where org.old_acct in ( select old_acct  from chg )  

如楼主所说“现在chg表有20万条记录”,那么别处不说,光着这条语句就造成每次update都要对一个20w行的表(chg)执行一次full scan。

论坛徽章:
0
17 [报告]
发表于 2007-09-10 21:15 |只看该作者
建议用循环, 用rowid做更新,每 1000条commit 一下,速度会很快!

论坛徽章:
0
18 [报告]
发表于 2007-09-11 11:05 |只看该作者
原帖由 numenhuang 于 2007-9-10 17:29 发表
比如要更新org.old_acct1,无索引字段
1. 创建临时表 t

2. insert into t select org.old_acct,chg.new_acct,chg_acct1 from org,chg where chg.old_acct1 = org.old_acct
不知道你数据库版本和优化器是什 ...


谈一下看法,因为org表数据在chg表中的数据匹配率很高,所以创建的临时表效果不大。
请教一下, in 与 exists效率相差多大。

论坛徽章:
0
19 [报告]
发表于 2007-09-11 11:07 |只看该作者
现在的进展如何

如果这个表此时没有并发访问,也可以考虑使用rowid

in和exists差别就在于这个子查询如何返回结果
in 会扫描所有符合条件的结果
exists找到第一条匹配的结果就返回

[ 本帖最后由 numenhuang 于 2007-9-11 11:08 编辑 ]

论坛徽章:
0
20 [报告]
发表于 2007-09-11 11:11 |只看该作者
原帖由 天涯明月刀 于 2007-9-10 18:00 发表


逻辑上有问题,

where org.old_acct in ( select old_acct  from chg )  

如楼主所说“现在chg表有20万条记录”,那么别处不说,光着这条语句就造成每次update都要对一个20w行的表(chg)执行一次ful ...


我认为主要瓶颈在于用到了两次select查询。
对于20万条记录,2分查找(我想oracle不至于傻到线性查找),也是很快的。
这问题如果用程序设计,是很简单的,线性时间而已; 但是数据库没想到相应的方法。
我试过merge,但是报错:merge中select,update不能同一个字段
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP