分别有两个查询,需要更新第一个查询中不在第二个查询中记录的某个字段。我用一个类似的sql例子说明查询1: select a.name,b.value from a,b where a.keyid=b.keyid
查询2: select c.name,d.value from c,d where c.keyid=d.keyid两者minus的结果中的记录对应的b表的字段time需要更新。b和d数据量在接近千万,a和c数据量在百万量级。本来想用minus,因为听说数据量大的时候,虽然minus会sort,但是据说比表联合查询快。但是不知道使用minus怎么写这个update语句。
我用的方法是用exists,但是速度实在是大家帮我想想该怎么提高这个速度update b set b.time=sysdate-1
where not exists
(select 1 from a,c,d where c.keyid=d.keyid and
a.keyid=b.keyid and
a.name=c.name and
b.value=d.value
);这个已经是最优的方法了吗?
查询2: select c.name,d.value from c,d where c.keyid=d.keyid两者minus的结果中的记录对应的b表的字段time需要更新。b和d数据量在接近千万,a和c数据量在百万量级。本来想用minus,因为听说数据量大的时候,虽然minus会sort,但是据说比表联合查询快。但是不知道使用minus怎么写这个update语句。
我用的方法是用exists,但是速度实在是大家帮我想想该怎么提高这个速度update b set b.time=sysdate-1
where not exists
(select 1 from a,c,d where c.keyid=d.keyid and
a.keyid=b.keyid and
a.name=c.name and
b.value=d.value
);这个已经是最优的方法了吗?
解决方案 »
- oracle安装问题:关于Oracle Net Configuration Assistant失败
- 没有人碰到过的问题.net 连到oracle服务器后只有简单的语句可以查询数据
- 正在执行查询时候,数据发生变化会出现什么情况
- 求助!
- 请教oracle9i在AIX上的奇怪问题
- 请问一次执行的sql语句是否有长度限制,如果有,那么该怎么解决呢?
- 请各位老大帮小弟写个简单的触发器,不盛感激!
- 如何实现定期向修改某张表中指定字段的问题?
- 丢失控制文件但是日志齐全能否完全恢复数据库?
- oracle 单独执行插入语句速度很快,放到存储过程里面就特别慢。
- 如何 查询出oralce用户的表的所有“列”(包含其他用户共享给他的表) < 给我上次提的问题不同上次是查询表这次是查询列 >
- oracle 实列自动创建
这个任务可以使用minus完成吗?
所以将节点名字先用cursor提取出来,在循环处理,循环体中的sql语句还是上面的,只不过多了对每个表的节点字段内容的限制。
现在的速度就快多了。结论:一个大的sql有时候不如循环执行的小的sql速度快。
你可以先建个临时表
create table temp as
select b.keyid,b.value from a,b,c,d where c.keyid=d.keyid and
a.keyid=b.keyid and
a.name=c.name and
b.value=d.value
然后对这个临时表两个列建复合索引
然后更新
update b set b.time=sysdate-1
where not exists
(select 1 from temp t where b.keyid=t.keyid and b.value=t.value);
我的方法用上后,原来要1个小时的问题,现在在3分钟解决。实际中的语句比这个要复杂的多,不单只是abcd四个表,也不是只有keyid,name来匹配就够了,实际中的匹配条件很多,所以我最早说的方法很慢。楼上的这个做法我再试一下,但是怀疑给临时表插入数据的那个select语句会执行很久,至少超过7分钟吧,如果算上所有的表,在这个查询中会有两张千万量级的表,两张百万量级,还有几个几千条的小表,也不会快的。我的方法是这样的,我还是用存储过程,然后使用了minus的方法,因为用节点来限制了minus前后的记录条数,所以minus很快。(minus的前后查询出来的结果都不超过10000条)。在循环体中用游标取一个个节点名字代入这个minus中求差。然后基于差值的结果做update,
单次循环控制在了600ms以下。所以最后七分钟以内就处理完成了。我实践中这样确实至少比我最早的全部一起的那种 not exists的方法快。在同样的一个目的,但是不是abcd中只有两个大表的一个任务中,我就直接使用了上面的not exists的方法,验证发现这种情况下not exists比这种分节点的方式要快,我的例子中大概耗用时间分别是8秒和20秒。还有一个问题想讨论楼上的这种方法,你查询出来要插入临时表的数据在我的例子中会达到千万级别,这样一个插入很慢,因为涉及到redo之类的东西,但是在我的方法中,每个循环内部我都可以commit,也节省了这个消耗。我的经验是这样感觉的,不知道是不是这个原因