-- ############################################################################################# -- -- %Purpose: How to reclaim UNUSED_SPACE from Indexes and Tables using DBMS_SPACE.UNUSED_SPACE -- -- Before growing a datafile in a tablespace that shows on your -- space analysis reports, search for space that can be reclaimed -- from an object that was poorly sized initially. Tables and indexes -- can be altered with a deallocate unused, thus reclaiming unused -- space above the high-water mark. -- -- Example: ALTER TABLE emp DEALLOCATE UNUSED; -- -- This script prompts you for two pieces of information: -- -- 1. The type of segment to retrieve, (i=indexes, t=tables) -- -- 2. The tablespace_name to retrieve from. -- -- Simply put, this allows you to retrieve one of these segment -- types by tablespace_name. It is important to note that deallocating -- unused space became available with Oracle version 7.3. -- -- #############################################################################################-- -- accept type prompt "Enter the type of segment to check (i=index, t=table): " accept ts_name prompt "Enter the tablespace name that you wish to check: " set serveroutput on feedback off -- spool unused_space.lst -- DECLARE v_total_blocks NUMBER; v_total_bytes NUMBER; v_unused_blocks NUMBER; v_unused_bytes NUMBER; v_file_id NUMBER; v_block_id NUMBER; v_last_block NUMBER; v_used NUMBER; v_owner VARCHAR2(12); v_segment VARCHAR2(80); v_type CHAR(1); CURSOR index_c is SELECT owner, index_name FROM sys.dba_indexes WHERE tablespace_name = upper('&ts_name'); CURSOR table_c is SELECT owner, table_name FROM sys.dba_tables WHERE tablespace_name = upper('&ts_name'); BEGIN DBMS_OUTPUT.ENABLE(100000); v_type := '&type'; IF (v_type = 'i' or v_type = 'I') THEN OPEN index_c; FETCH index_c into v_owner, v_segment; WHILE index_c%FOUND LOOP -- DBMS_SPACE.UNUSED_SPACE(v_owner, v_segment, 'INDEX', v_total_blocks, v_total_bytes, v_unused_blocks, v_unused_bytes, v_file_id, v_block_id, v_last_block); -- DBMS_OUTPUT.PUT_LINE(CHR(10)); DBMS_OUTPUT.PUT_LINE('Index Name = '||v_segment); DBMS_OUTPUT.PUT_LINE('Total Blocks = '||v_total_blocks); DBMS_OUTPUT.PUT_LINE('Total Bytes = '||v_total_bytes); DBMS_OUTPUT.PUT_LINE('Unused Blocks = '||v_unused_blocks); DBMS_OUTPUT.PUT_LINE('Unused Bytes = '||v_unused_bytes); v_used := v_total_blocks - v_unused_blocks; DBMS_OUTPUT.PUT_LINE('Used Blocks = '||v_used); v_used := v_total_bytes - v_unused_bytes; DBMS_OUTPUT.PUT_LINE('Used Bytes = '||v_used); DBMS_OUTPUT.PUT_LINE('Last used extents file id = '||v_file_id); DBMS_OUTPUT.PUT_LINE('Last used extents block id = '||v_block_id); DBMS_OUTPUT.PUT_LINE('Last used block = '||v_last_block); fetch index_c into v_owner, v_segment; END LOOP; CLOSE index_c; ELSIF (v_type = 't' or v_type = 'T') THEN OPEN table_c; FETCH table_c into v_owner, v_segment; WHILE table_c%FOUND LOOP -- DBMS_SPACE.UNUSED_SPACE(v_owner, v_segment, 'TABLE', v_total_blocks, v_total_bytes, v_unused_blocks, v_unused_bytes, v_file_id, v_block_id, v_last_block); -- v_used := v_total_bytes - v_unused_bytes; DBMS_OUTPUT.PUT_LINE(CHR(10)); DBMS_OUTPUT.PUT_LINE('Table Name = '||v_segment); DBMS_OUTPUT.PUT_LINE('Total Blocks = '||v_total_blocks); DBMS_OUTPUT.PUT_LINE('Total Bytes = '||v_total_bytes); DBMS_OUTPUT.PUT_LINE('Unused Blocks = '||v_unused_blocks); DBMS_OUTPUT.PUT_LINE('Unused Bytes = '||v_unused_bytes); v_used := v_total_blocks - v_unused_blocks; DBMS_OUTPUT.PUT_LINE('Used Blocks = '||v_used); v_used := v_total_bytes - v_unused_bytes; DBMS_OUTPUT.PUT_LINE('Used Bytes = '||v_used); DBMS_OUTPUT.PUT_LINE('. KBytes = '||v_used/1024); DBMS_OUTPUT.PUT_LINE('. MBytes = '||(v_used/1024)/1024); DBMS_OUTPUT.PUT_LINE('Last used extents file id = '||v_file_id); DBMS_OUTPUT.PUT_LINE('Last used extents block id = '||v_block_id); DBMS_OUTPUT.PUT_LINE('Last used block = '||v_last_block); fetch table_c into v_owner, v_segment; END LOOP; CLOSE table_c; END IF; END; / spool off