我的问题:
你们看我这个,1号的就走索引,4号的不走索引要全表,我希望4号走索引,加了强制走索引的语句也不管用,怎办?
(我的语句:)
update t_mt partition(P_MT5_1) mt set (mt.stat,mt.rpttime)=(select stat,rpttime from t_statbuf buf
where sj>=to_date('2013-05-04 00:00:00','yyyy-mm-dd hh24:mi:ss') and sj=to_date('2013-05-04 00:00:00','yyyy-mm-dd hh24:mi:ss') and mt.ctime=to_date('2013-05-04 00:00:00','yyyy-mm-dd hh24:mi:ss') and sj
merge into t_mt partition(P_MT5_1) mt
using (select *
from t_statbuf
where sj>=to_date('2013-05-05','yyyy-mm-dd')
and sj=to_date('2013-05-05','yyyy-mm-dd')
and mt.ctime
答:
我自己写的:
1.更新mt中有状态的,mx没取的到mx,从4-27号开始,大概更新200万行,预计时间30分钟:
merge into t_busi_presend_mx mx
using (select *
from t_mt
where ctime>=to_date('2013-04-27','yyyy-mm-dd')
) mt
on(mx.id=mt.mcid)
when matched then
update set mx.sjsendstatus=mt.stat,mx.rpttime=mt.rpttime
where mx.cjsj>=to_date('2013-04-27','yyyy-mm-dd')
and mx.sjsendstatus='NONE'
1.用的merge,删除200万条,用了535秒。(merge delete时,前面必须加update set)
merge into t_statbuf buf
using (select *
from t_mt
where ctime>=to_date('2013-04-27','yyyy-mm-dd')
) mt
on(buf.msgid=mt.msgid)
when matched then
update set buf.stat=null
delete where( buf.msgid=mt.msgid)
可以这样试试:
create table tmp_t1 nologgng as
select buf.msgid from buf,mt where buf.id=mt.id;
create table tmp_mt nologging as
select * from mt;
create index ... on tmp_mt(msgid);
delete from tmp_mt mt where exists
(select 1 from tmp_t1 t1 where mt.msgid=t1.msgid);
commit;
delete from buf where exists
(select 1 from tmp_t1 t1 where buf.msgid=t1.msgid);
commit;
insert into buf
select * from tmp_mt;
commit;
DELETE t_statbuf m2 WHERE EXISTS(SELECT m1.msgid FROM t_mt m1 WHERE ctime>=to_date('2013-04-27','yyyy-mm-dd') AND m1.msgid=m2.msgid)
merge 是比较实用,但是如果你遇到很大的数据量的更新,merge的效率也变差,你可能要做分批更新的操作,当然这种更新量也在千万级别的数据量 。
如果删除的数据小 buf和mt数据量大,就先把相同数据取出来,再用exists。