why after truncate the table space not returned when view object size in tablespace? - oracle

I am always use TRUNCATE TABLE to free up space and always the space returned to free space
when I check the free space in oracle tablespace I found the free space increased always
I am using TOAD program to
TRUNCATE TABLE
But this time different I truncated 2 tables but its not free the table space and when I checked
the table size after truncated its still same size used before around 400 MB
why its not free the space , and how to free the space table already truncated and no data in it.
also I moved the table to another tablespace after truncate but its moved with same size
ALTER TABLE CAS_NOSHOW MOVE TABLESPACE TRNG;
how to free up space please your help .
I am using oracle 10g database

If you're looking to recover space above and below the high water mark you can shrink the table.
To do this you need to have row movement enabled.
create table t as
select rownum x, lpad('x', 500, 'x') xx from dual connect by level <= 10000;
/
-- ALTER TABLE t SHRINK SPACE CHECK;
select bytes from user_segments
where segment_name = 'T';
/
delete t where x <= 9900;
/
select bytes from user_segments
where segment_name = 'T';
/
alter table t enable row movement;
/
alter table t shrink space CASCADE;
/
select bytes from user_segments
where segment_name = 'T';

Related

What is the data length of CLOB in oracle?

Could you please let me know what is the Data length for the 2nd column_id of "CLOB" data type in the Employee table? I see some blogs where it says maximum data length is : (4GB -1)* (database block size).
I'm new to this data designing.
Table : Employee
**Column_Name ----- Data_Type ------- Nullable ---- Column_Id**
Emp_ID NUMBER No 1
Emp_details CLOB NO 2
Please help me.
To get CLOB size for a given column in a given row, use DBMS_LOB.GETLENGTH function:
select dbms_lob.getlength(emp_details) from employee from emp_id=1;
To get CLOB size for a given column in a given table that is allocated in the tablespace, you need to identify both segments implementing the LOB.
You can compare both size with following query:
select v1.col_size, v2.seg_size from
(select sum(dbms_lob.getlength(emp_details)) as col_size from employee) v1,
(select sum(bytes) as seg_size from user_segments where segment_name in
(
(select segment_name from user_lobs where table_name='EMPLOYEE' and column_name='EMP_DETAILS')
union
(select index_name from user_lobs where table_name='EMPLOYEE' and column_name='EMP_DETAILS')
)
) v2
;
LOBs are not stored in the table, but outside of it in a dedicated structure called LOB segment, using an LOB index. As #pifor explains, you can inspect those structures in the dictionary view user_lobs.
The LOB segment uses blocks of usually 8192 bytes (check the tablespace in user_lobs), so the minimum size allocated for a single LOB is 8K. For 10.000 bytes, you need two 8K blocks and so on.
Please note that if your database is set to Unicode (as most modern Oracle databases are), the size of a CLOB is roughly 2x as expectet, because they are stored in a 16 bit encoding.
This gets a bit better if you compress the LOBs, but your Oracle license needs to cover "Advanced Compression".
For very small LOBs (less than ca 4000 bytes), you can avoid the 8K overhead and store them in the table where all the other columns are (enable storage in row).

Oracle - how to see how many blocks have been used in a table

I have very limited experience when using Oracle, and am after a rather simple query I imagine. I have a table which contains 1 million rows, Im trying to proof that compressing the data uses less space, however im not sure how to do this, based on this table creation below could someone please show me what i need to write to see the blocks used before/after?
CREATE TABLE OrderTableCompressed(OrderID, StaffID, CustomerID, TotalOrderValue)
as (select level, ceil(dbms_random.value(0, 1000)),
ceil(dbms_random.value(0,10000)),
round(dbms_random.value(0,10000),2)
from dual
connect by level <= 1000000);
ALTER TABLE OrderTableCompressed ADD CONSTRAINT OrderID_PKC PRIMARY KEY (OrderID);
--QUERY HERE THAT SHOWS BLOCKS USED/TIME TAKEN
SELECT COUNT(ORDERID) FROM OrderTableCompressed;
ALTER TABLE OrderTableCompressed COMPRESS;
--QUERY HERE THAT SHOWS BLOCKS USED/TIME TAKEN WHEN COMPRESSED
SELECT COUNT(ORDERID) FROM OrderTableCompressed;
I know how the compression works etc... its just applying the code to proove my theory. thanks for any help
--QUERY HERE THAT SHOWS BLOCKS USED
SELECT blocks, bytes/1024/1024 as MB
FROM user_segments
where segment_name = 'ORDERTABLECOMPRESSED';
Now compress the table: (Note the move. Without it you just change the attribute of the table and subsequent direct path inserts will create compressed blocks)
ALTER TABLE OrderTableCompressed MOVE COMPRESS;
Verify blocks:
--QUERY HERE THAT SHOWS BLOCKS USED TAKEN WHEN COMPRESSED
SELECT blocks, bytes/1024/1024 as MB
FROM user_segments
where segment_name = 'ORDERTABLECOMPRESSED';

Release unused space of USERS tablespace in oracle

I have lots of table with lots of records in oracle 11g. (more than 2 billions) After applying some queries and creating some indexes I am so close to insufficient disk space. Right now for executing each query ORA-01652 error for USERS tablespace appears. I cannot add more datafile to USERS tablespace anymore because of insufficient disk space. I am sure that there are lots of unused space available on this tablespace that is not usable somehow. (I deleted some tables and indexes nothing happened) My question is how can I release this space? Thank you very much.
I don't know if you can to it for an entire tablespace but for a single table the command is:
ALTER TABLE MY_TABLE ENABLE ROW MOVEMENT; -- By defaut ROW MOVEMENT is disabled when you create a table.
ALTER TABLE MY_TABLE SHRINK SPACE CASCADE;
ALTER TABLE MY_TABLE DEALLOCATE UNUSED;
Maybe you have to loop over ALL_TABLES in your schema.
Then you can gain disc space by rebuilding your indexes.
ALTER INDEX THE_INDEX REBUILD;

Oracle Table Size without Data

Is it possible to have a table that reports a size but does not have any rows in it? When I run the following query one of the tables reports a size but does not contain any rows. How is this possible?
select table_name,
b.tablespace_name,
sum( bytes)/1024/1024 "SIZE IN MB"
from USER_segments a,
user_tables b
where table_name=segment_name
group by segment_name,
b.tablespace_name,
table_name;
Table segements grow when data is inserted into them. Since 11g a new created table can be created without a segment. When data is inserted into such a newly created table, the segment is created.
The space that is occupied by the segment is not automatically returned to the free space in the datafile when rows are deleted. So, your table is created empty with direct segment creation, or it had rows and they are deleted.

Table compression requirements in Oracle

I have a Tablespace with total Size 600 MB(this is my test machine), and free space of 110 MB. I was trying to compress a table that's size is 120 MB. When execute the commands:
alter table DOWNLOADSESSIONLOG move compress;
I'm getting error saying:
(Error): ORA-01659: unable to allocate MINEXTENTS beyond 16 in tablespace WAP.
I was searching and all are saying to increase the Tablespace, but I wanted to know how much space I need to give, because I don't want to gave some 200 /300 MB extra space. I wanted to test this in my Test Machine and wanted to implement on Live system that have 60 GB tablespace with one 47 GB table. I wanted to compress 47 GB table on live system, before that I wanted to test it in test environment. Is there any calculation how much space we need to give; otherwise on live system I need to give Lots of space unnecessarily and its difficult.
Appreciate somebody can give some ideas.
I would create a new throw-away tablespace in your test environment that has the same characteristics as your target tablespace in the production environment and then move/compress your table into that. This will give you the best estimate of how much additional space will be necessary. You can move the table back to the original tablespace and drop the new tablespace once you have this number.
Remember that you'll need at least (original size) + (compressed size) available in the tablespace for the duration of the move.
The key thing about compression is that it works by removing duplicate values in each block. So your test table needs to have a representative spread of data.
Two extreme tables ...
SQL> create table totally_similar
2 ( txt varchar2(1000) )
3 /
Table created.
SQL> insert into totally_similar
2 select rpad('a', 1000, 'a')
3 from dual connect by level <= 1000
4 /
1000 rows created.
SQL> create table totally_different
2 ( txt varchar2(1000) )
3 /
Table created.
SQL>
Before we compress let's just check the table sizes...
SQL> insert into totally_different
2 select dbms_random.string('A',1000)
3 from dual connect by level <= 1000
4 /
1000 rows created.
SQL> select segment_name
2 , sum(bytes)
3 , sum(blocks)
4 from user_segments
5 where segment_name in ('TOTALLY_SIMILAR', 'TOTALLY_DIFFERENT')
6 group by segment_name
7 /
SEGMENT_NAME SUM(BYTES) SUM(BLOCKS)
-------------------- ---------- -----------
TOTALLY_SIMILAR 2097152 256
TOTALLY_DIFFERENT 2097152 256
SQL>
If we compress them we get two radically different results ...
SQL> alter table totally_similar move compress
2 /
Table altered.
SQL> alter table totally_different move compress
2 /
Table altered.
SQL> select segment_name
2 , sum(bytes)
3 , sum(blocks)
4 from user_segments
5 where segment_name in ('TOTALLY_SIMILAR', 'TOTALLY_DIFFERENT')
6 group by segment_name
7 /
SEGMENT_NAME SUM(BYTES) SUM(BLOCKS)
-------------------- ---------- -----------
TOTALLY_SIMILAR 65536 8
TOTALLY_DIFFERENT 2097152 256
SQL>
Note that TOTALLY_SIMILAR is eight blocks big, even though every single row was the same. So you need to understand the distribution of your data before you can calculate the compression ratio. The Oracle documentation has this to say:
The compression factor that can be
achieved depends on the cardinality of
a specific column or column pairs
(representing the likelihood of column
value repetitions) and on the average
row length of those columns. Oracle
table compression not only compresses
duplicate values of a single column
but tries to use multi-column value
pairs whenever possible.
Its advice when it comes to estimation of the return is that a sample table of 1000 blocks of the target table should give you a good enough prediction (although more blocks give a more accurate forecast). It is hard to tell without knowing your blocksize, but it seems likely that your TEST table is much bigger than it needs to be. The important thing is whether the data in the test table is representative of your target table. So, did you create it using an export or a sample from the target table, e.g.
create table test_table as select * from big_table sample block (1)
/
You will need to adjust the percentage in the SAMPLE() clause to ensure you get at least 1000 blocks.
edit
In most cases compression should actually speed up data retrieval but YMMV. The cost of compression is paid when inserting or updating the data. How much that tax is and whether you can do anything to avoid it rather depends on the profile of your table.

Resources