Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Ashish.

Asked: September 01, 2000 - 9:55 am UTC

Last updated: October 01, 2005 - 8:30 pm UTC

Version: 8.1.5.0.0

Viewed 1000+ times

You Asked

I have a partitioned table with 175 million records. The table
has 7 partitions with 25 million records in each. I want to drop
5 columns from this table. These columns does not have any
indexes on them. What would be the best way to do it?
Thanks for your help!

and Tom said...


In Oracle8i you can drop and set unused various columns in a table. The big difference between the two is DROP will physically reclaim space (rewrites the data) whereas SET UNUSED is a flag delete -- the columns are gone (and you can never get them back) however it happens very fast since the data is not rewritten. At some time in the future, you can DROP UNUSED to reclaim the space if you want.

For that table, I would probably use the

alter table T set unused column X;

to remove them.


Rating

  (3 ratings)

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

Comments

How do you tell which columns are unused?

John, July 08, 2002 - 11:54 am UTC

Is there anyway to tell which columns have been flagged as unused? The documentation shows how to find the number of columns flagged as unused.

SELECT * FROM DBA_UNUSED_COL_TABS;

But it doesn't show how you find the names or attributes of the unused columns.

Tom Kyte
July 08, 2002 - 4:38 pm UTC

Well, I don't see why it is relevant (i mean, you cannot recover them - only that they are there taking up space is all that matters). But, since you asked anyway

In looking at the view:


create or replace view dba_unused_col_tabs (
OWNER
,TABLE_NAME
,COUNT
) as
select u.name, o.name, count(*)
from sys.user$ u, sys.obj$ o, sys.col$ c
where c.obj# = o.obj#
and bitand(c.property,32768) = 32768 -- is unused column
and bitand(c.property, 1) != 1 -- not ADT attribute col
and bitand(c.property, 1024) != 1024 -- not NTAB's setid col
and u.user# = o.owner#
group by u.name, o.name

/

we see we could suck some of the data out from sys.col$. You will find however the column name is "wiped out" (replaced with SYS_C...... stuff). That is so the unique index on col$(obj#,name) is obeyed if you add a column back with the same name....

So, the name is gone, but the datatype and size is still there. If you take the above view and hack out a bit from the DBA_TAB_COLUMNS view, you can get:

select u.name, o.name,
decode(c.type#, 1, decode(c.charsetform, 2, 'NVARCHAR2', 'VARCHAR2'),
2, decode(c.scale, null,
decode(c.precision#, null, 'NUMBER', 'FLOAT'),
'NUMBER'),
8, 'LONG',
9, decode(c.charsetform, 2, 'NCHAR VARYING', 'VARCHAR'),
12, 'DATE', 23, 'RAW', 24, 'LONG RAW',
69, 'ROWID',
96, decode(c.charsetform, 2, 'NCHAR', 'CHAR'),
105, 'MLSLABEL',
106, 'MLSLABEL',
111, 'unknown',
112, decode(c.charsetform, 2, 'NCLOB', 'CLOB'),
113, 'BLOB', 114, 'BFILE', 115, 'CFILE',
121, 'unknown',
122, 'unknown',
123, 'unknown',
178, 'TIME(' ||c.scale|| ')',
179, 'TIME(' ||c.scale|| ')' || ' WITH TIME ZONE',
180, 'TIMESTAMP(' ||c.scale|| ')',
181, 'TIMESTAMP(' ||c.scale|| ')' || ' WITH TIME ZONE',
231, 'TIMESTAMP(' ||c.scale|| ')' || ' WITH LOCAL TIME ZONE',
182, 'INTERVAL YEAR(' ||c.precision#||') TO MONTH',
183, 'INTERVAL DAY(' ||c.precision#||') TO SECOND(' ||
c.scale || ')',
208, 'UROWID',
'UNDEFINED'),
c.length, c.precision#, c.scale
from sys.user$ u, sys.obj$ o, sys.col$ c
where c.obj# = o.obj#
and bitand(c.property,32768) = 32768 -- is unused column
and bitand(c.property, 1) != 1 -- not ADT attribute col
and bitand(c.property, 1024) != 1024 -- not NTAB's setid col
and u.user# = o.owner#
/


which shows you the stuff that we can see.

What about rollback?

Doug, July 08, 2002 - 9:06 pm UTC

Tom - I have noticed that droping a column can take a lot of rollback and time even on a million row table. (These terms being relative of course). Will using the set unused option prior to actually dropping them assist with this or not?

Tom Kyte
July 09, 2002 - 7:08 am UTC

No, setting unused is simply a flag delete -- the space is not reclaimed.

Later, when you drop, it does EXACTLY the work that would have been done by DROP COLUMN in the first place.

You know -- you can incrementally checkpoint the drop column command as it is going along.

Yes, it can take a relatively long time to REWRITE a 1,000,000 row table depending on your system.

Big Table = "set unused"
Small Table = "drop column"

big and small being relative terms of course.

import/export

A reader, September 30, 2005 - 4:57 pm UTC

hello tom.

I marked 10 fields in my 5M row table as unused.
then exported it.
and then imported it in the development schema,
and ran some insert update scripts (nothing drop)

than I ran both the user_unused_col_tab and
your query but I still don't see any unused column
in the newly imported schema in dev.

what is wrong ? or is it just me ?

Tom Kyte
October 01, 2005 - 8:30 pm UTC

it is a new table, this new table hasn't any "unused" columns???

only the original table would have them.