Skip to Main Content

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, swadesh.

Asked: August 23, 2017 - 12:22 pm UTC

Last updated: August 23, 2017 - 4:58 pm UTC

Version: Oracle 12C

Viewed 1000+ times

You Asked

Hi,

I have a 2TB table. It has also large index.

I want to delete records from this large table with date key. Date key is a column in side table. Below is my query. But it takes huge time.


delete /*+ PARALLEL(6)*/ FROM F_CUST_TRANSACTION_LINE_ITEMS where DATE_KEY<to_number(TO_CHAR(trunc(sysdate)-823,'YYYYMMDD'));

Please suggest how can we make it fastest delete statement or provide some sample syntax for delete.

Regards,
Swadesh

and Chris said...

You mean you haven't heard of the fast_delete command?!



...




That's because it doesn't exist. Deleting lots of rows is going to take a while. The only faster way is truncate - but that removes everything!

You've got a parallel hint, which may help it run faster. But only if you've enabled parallel DML!

Ensure you run this first:

ALTER SESSION ENABLE PARALLEL DML;


If that's not helping, you could look into:

Disabling indexes on the table

But, of course, any queries needing and using those indexes will be slower while your delete runs. So you're just trading one slow statement for (lots of) others. And you'll have to rebuild them afterwards which will take (possibly a looooooong) time.

Indexing date_key

Assuming it isn't already indexed. And you're deleting a small enough fraction of the table that execution plan will use it instead of a full table scan.

Obviously, this contradicts the previous suggestion.

If neither of these help enough, you may need to look into more radical solutions.

Such as saving the data you want to keep in a temporary table. Then dropping the current table and renaming the temporary one. e.g.:

create table tmp as select ...data you want to keep... from old_tab;
drop old_tab;
rename tmp to old_tab;
-- run grants, indexes etc. that were on the original table
...


But you need an outage to do this. Unless you're good with your users getting a stack of errors when you drop the current table ;)

And there's the risk of forgetting to migrate indexes or whatever from the old table to the new...

Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

RE

GJ, August 23, 2017 - 2:49 pm UTC

delete /*+ PARALLEL(6)*/ FROM F_CUST_TRANSACTION_LINE_ITEMS where DATE_KEY<to_number(TO_CHAR(trunc(sysdate)-823,'YYYYMMDD'));

--Some assumptions
i guess you are trying to delete from a large fact table F_CUST_TRANSACTION_LINE_ITEMS where date_key is less that a value.
Is your 2TB table partitioned on the DATE_KEY?

If not then you can include the partition key as part of the delete clause, which can speed up the deletes



Chris Saxon
August 23, 2017 - 4:53 pm UTC

There's no mention of partitioning in the original question...

swadesh Mondal, August 23, 2017 - 3:16 pm UTC

Hi,

I am not impressed about your answer.
Drop ,recreate is not possible,because this is huge amount of table.Also parallel is enabled but still taking much more time.

Please provide some feasible option.

Regards,
Swadesh
Chris Saxon
August 23, 2017 - 4:56 pm UTC

And I'd like to eat unlimited quantities of cake without gaining weight or getting diabetes.

But that's not a feasible option.

Sometimes there are no better solutions.

Plan for Partition

A reader, August 23, 2017 - 3:19 pm UTC

If this is something that you are going to do from time to time (monthly, once a year, etc).

I would be a good idea to do the create table as select .... partition ( monthly partition)

So that later you can just drop the partitions, and do not have an outage again
Chris Saxon
August 23, 2017 - 4:58 pm UTC

Yep, they could partition the table using DBMS_redefinition with a minimal outage. And future "deletes" would be fast.

More to Explore

SQL

The Oracle documentation contains a complete SQL reference.