Reputation: 83
I used this code but it takes too long, and the computer crashes:
begin
for i In 0..1000
loop
delete from mytable WHERE user_date BETWEEN to_char(to_date('20120101000000','YYYYMMDD')+i,'YYYYMMDDHH24MISS') and to_char(to_date('20120101235959','YYYYMMDD')+i,'YYYYMMDDHH24MISS');
end loop;
end;
I think I need to apply bulk SQL to this code.
I have to erase the data in the 2 year range
Please help me.
user_date type is char (20120101000000)
Upvotes: 0
Views: 176
Reputation: 2028
Which version of Oracle are you using? If 19c, the you can do
alter table mytable move including rows where user_date NOT BETWEEN '20120101000000' AND '20150101000000' online.
Upvotes: 0
Reputation: 8361
72.000.000 rows is a lot, so special measures are in order. I'd count how many rows will be deleted and how many will be kept with f.i.:
SELECT todo, count(*) FROM (
SELECT CASE
WHEN user_date BETWEEN '20120101000000' AND '20150101000000'
THEN 'delete'
ELSE 'keep'
END AS todo
FROM mytab
) GROUP by todo;
As @Littlefoot said, if a large enough amount is to be deleted, I'd try the CTAS approach:
CREATE TABLE mytemp NOLOGGING AS
SELECT * FROM mytable
WHERE user_date NOT BETWEEN '20120101000000' AND '20150101000000';
DROP TABLE mytable;
RENAME mytemp TO mytable;
Caution: You'll have to recreate all indexes, privileges, etc. Please try this on a test system preferably on a small example.
If, on the other hand, only a small percentage of rows will be deleted, and the rest will be kept, I'd follow @Tim Biegeleisen's approach:
CREATE INDEX i ON mytable(user_date);
DELETE FROM mytable
WHERE user_date BETWEEN '20120101000000' AND '20150101000000';
If you follow the second approach, and the number of rows is still substantial, you'll might need to free up the space by reorganizing the table. Ask a DBA about it.
If you don't have a test system, you can create on by copying a small sample (say 0.1%) of your huge table:
CREATE TABLE mytest NOLOGGING AS SELECT * FROM mytable (SAMPLE 0.1);
I didn't fully understand your date logic, therefore used all dates from 2012-01-01 till 2014-12-31 in my examples.
Oh, and yes, @a_horse_with_no_name is totally right, never store dates in varchar.
Upvotes: 1