我要定时清理一个有大对象的AQ_Queue表,方法是先锁,然后取要保留的数据到临时表,然后truncate,然后把数据放回,然后truncate临时表,写了2个procedure,都工作,但是最后是drop掉临时表好还是留空临时表只是truncate它?
1,先手工建立临时表
DECLARE
CURSOR c1 is select name1,name2,del_stat from tc;
aq_name tc.name1%type;
temp_name tc.name2%type;
del_stat tc.del_stat%type;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO aq_name, temp_name,del_stat;
EXIT WHEN c1%NOTFOUND;
EXECUTE IMMEDIATE 'LOCk TABLE '||aq_name||' IN EXCLUSIVE MODE';
EXECUTE IMMEDIATE 'INSERT INTO '||temp_name||' SELECT * FROM '||aq_name||' WHERE stat != '||del_stat;
EXECUTE IMMEDIATE 'TRUNCATE TABLE '||aq_name;
EXECUTE IMMEDIATE 'INSERT INTO '||aq_name||' SELECT * FROM '||temp_name;
EXECUTE IMMEDIATE 'TRUNCATE TABLE '||temp_name;
END LOOP;
COMMIT;
CLOSE c1;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
END;
2,不用事先建立临时表
--t2.sql
DECLARE
CURSOR c1 is select name1,del_stat from tc;
aq_name tc.name1%type;
del_stat tc.del_stat%type;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO aq_name, del_stat;
EXIT WHEN c1%NOTFOUND;
EXECUTE IMMEDIATE 'LOCK TABLE '||aq_name||' IN EXCLUSIVE MODE';
EXECUTE IMMEDIATE 'CREATE TABLE temp AS SELECT * FROM '||aq_name||' WHERE stat != '||del_stat;
EXECUTE IMMEDIATE 'TRUNCATE TABLE '||aq_name;
EXECUTE IMMEDIATE 'INSERT INTO '||aq_name||' SELECT * FROM temp';
EXECUTE IMMEDIATE 'DROP TABLE temp';
END LOOP;
COMMIT;
CLOSE c1;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
END;
问题1,先手工建立临时表和在过程里建相比,长远定时任务中,哪个更有效率?
问题2,最后是drop掉临时表好还是留空临时表只是truncate它?哪个更容易造成碎片?