Scripts:此脚本慎用lob_fragmentation_user.sql
来源:互联网 发布:循环大批量更新数据库 编辑:程序博客网 时间:2024/06/05 17:00
-- +----------------------------------------------------------------------------+
-- | Jeffrey M. Hunter |
-- | jhunter@idevelopment.info |
-- | www.idevelopment.info |
-- |----------------------------------------------------------------------------|
-- | Copyright (c) 1998-2012 Jeffrey M. Hunter. All rights reserved. |
-- |----------------------------------------------------------------------------|
-- | DATABASE : Oracle |
-- | FILE : lob_fragmentation_user.sql |
-- | CLASS : LOBs |
-- | PURPOSE : When a LOB segment is first created, its initial "allocated" |
-- | size is 64K, even though there are no rows in the table. As LOB |
-- | data is entered into the LOB segment, the allocated space for |
-- | the segment will continue to increase. If over time, the LOB |
-- | segment starts to experience many deletes and updates, it is |
-- | possible for the LOB segment to become fragmented and possibly |
-- | waste a considerable amount of disk space. This occurs when the |
-- | size of the actual LOB segment data is considerably less than |
-- | what is allocated by the LOB segment. Consider a situation |
-- | where a LOB segment has 16GB allocated for the segment but only |
-- | contains 2GB worth of actual LOB data. Potentially, this is |
-- | nearly 14GB of wasted allocated space. This could occur when a |
-- | significant number of rows have been deleted from the table |
-- | storing the LOB column. |
-- | |
-- | This script can be used to identify the size and amount of |
-- | fragmentation that exists in all LOB segments for a particular |
-- | user. |
-- | |
-- | To reclaim the wasted space within a fragmented LOB segment, |
-- | use the following SQL command: |
-- | |
-- | ALTER TABLE <OWNER>.<TABLE_NAME> MODIFY LOB (<LOB_COLUMN>) (SHRINK SPACE);
-- | |
-- | NOTE: The time required to shrink the LOB segment is a function |
-- | of how much data needs to be coalesced. In many cases, |
-- | the shrink operation can take minutes or possibly several |
-- | hours depending on the amount of data that needs to be |
-- | moved. |
-- | |
-- | NOTE : As with any code, ensure to test this script in a development |
-- | environment before attempting to run it in production. |
-- +----------------------------------------------------------------------------+
SET TERMOUT OFF;
COLUMN current_instance NEW_VALUE current_instance NOPRINT;
COLUMN current_user NEW_VALUE current_user NOPRINT;
SELECT rpad(instance_name, 17) current_instance, rpad(user, 13) current_user FROM v$instance;
SET TERMOUT ON;
PROMPT
PROMPT +------------------------------------------------------------------------+
PROMPT | Report : LOB Fragmentation for the Current User |
PROMPT | Instance : ¤t_instance |
PROMPT | User : ¤t_user |
PROMPT +------------------------------------------------------------------------+
PROMPT
SET ECHO OFF
SET FEEDBACK 6
SET HEADING ON
SET LINESIZE 180
SET PAGESIZE 50000
SET TERMOUT ON
SET SERVEROUTPUT ON
SET TIMING OFF
SET TRIMOUT ON
SET TRIMSPOOL ON
SET VERIFY OFF
CLEAR COLUMNS
CLEAR BREAKS
CLEAR COMPUTES
declare
v_actual_length number;
v_allocated_length number;
v_lob_fragmentation_pct number;
v_actual_length_char varchar2(50);
v_allocated_length_char varchar2(50);
v_statement varchar2(2000);
v_table_column_pad_length constant number := 45;
v_actual_length_pad_length constant number := 20;
v_allocated_length_pad_length constant number := 20;
v_fragmentation_pad_length constant number := 15;
begin
dbms_output.enable(1000000);
-- Print column headers
dbms_output.put_line( rpad('LOB COLUMN - [OWNER.TABLE.COLUMN]', v_table_column_pad_length) || ' ' ||
lpad('ALLOCATED LOB LENGTH', v_allocated_length_pad_length) || ' ' ||
lpad('ACTUAL LOB LENGTH', v_actual_length_pad_length) || ' ' ||
lpad('FRAGMENTATION', v_fragmentation_pad_length)
);
dbms_output.put_line( rpad('-', v_table_column_pad_length, '-') || ' ' ||
lpad('-', v_allocated_length_pad_length, '-') || ' ' ||
lpad('-', v_actual_length_pad_length, '-') || ' ' ||
lpad('-', v_fragmentation_pad_length, '-')
);
-- Get all LOB segments for the current user
for v_lob_segment in (select user, l.table_name, l.column_name
from user_lobs l join user_segments s
using (segment_name, tablespace_name)
where l.column_name not like '"%'
order by 2,3)
loop
dbms_output.put(rpad(v_lob_segment.user || '.' || v_lob_segment.table_name || '.' || v_lob_segment.column_name, v_table_column_pad_length));
dbms_output.put(' ');
-- Get "allocated size" of the LOB segment
v_statement := 'begin '
|| 'select to_char(a.bytes, ''999,999,999,999,999'') '
|| 'into :col_val2 '
|| 'from user_segments a join user_lobs b '
|| 'using (segment_name) '
|| 'where b.table_name = ''' || v_lob_segment.table_name || ''''
|| ' and b.column_name = ''' || v_lob_segment.column_name || ''';'
|| 'end;';
execute immediate v_statement using out v_allocated_length_char;
v_allocated_length_char := regexp_replace(v_allocated_length_char, ' ', '');
v_allocated_length := regexp_replace(v_allocated_length_char, ',', '');
dbms_output.put(lpad(v_allocated_length_char, v_allocated_length_pad_length));
dbms_output.put(' ');
begin
-- Get "actual size" of the LOB segment
v_statement := 'begin '
|| 'select to_char(sum(dbms_lob.getlength(' || v_lob_segment.column_name || ')), ''999,999,999,999,999'' ) '
|| 'into :col_val1 '
|| 'from ' || v_lob_segment.table_name || ';'
|| 'end;';
execute immediate v_statement using out v_actual_length_char;
v_actual_length_char := nvl(regexp_replace(v_actual_length_char, ' ', ''), '0');
v_actual_length := nvl(regexp_replace(v_actual_length_char, ',', ''), 0);
dbms_output.put(lpad(v_actual_length_char, v_actual_length_pad_length));
dbms_output.put(' ');
-- Calculate LOB fragmentation
if v_actual_length = 0 then
v_actual_length := v_allocated_length;
end if;
v_lob_fragmentation_pct := round(((1-(v_actual_length/v_allocated_length))*100), 2);
dbms_output.put(lpad(v_lob_fragmentation_pct || ' %', v_fragmentation_pad_length));
exception
when others then null;
end;
dbms_output.put_line('');
end loop;
end;
/
-- | Jeffrey M. Hunter |
-- | jhunter@idevelopment.info |
-- | www.idevelopment.info |
-- |----------------------------------------------------------------------------|
-- | Copyright (c) 1998-2012 Jeffrey M. Hunter. All rights reserved. |
-- |----------------------------------------------------------------------------|
-- | DATABASE : Oracle |
-- | FILE : lob_fragmentation_user.sql |
-- | CLASS : LOBs |
-- | PURPOSE : When a LOB segment is first created, its initial "allocated" |
-- | size is 64K, even though there are no rows in the table. As LOB |
-- | data is entered into the LOB segment, the allocated space for |
-- | the segment will continue to increase. If over time, the LOB |
-- | segment starts to experience many deletes and updates, it is |
-- | possible for the LOB segment to become fragmented and possibly |
-- | waste a considerable amount of disk space. This occurs when the |
-- | size of the actual LOB segment data is considerably less than |
-- | what is allocated by the LOB segment. Consider a situation |
-- | where a LOB segment has 16GB allocated for the segment but only |
-- | contains 2GB worth of actual LOB data. Potentially, this is |
-- | nearly 14GB of wasted allocated space. This could occur when a |
-- | significant number of rows have been deleted from the table |
-- | storing the LOB column. |
-- | |
-- | This script can be used to identify the size and amount of |
-- | fragmentation that exists in all LOB segments for a particular |
-- | user. |
-- | |
-- | To reclaim the wasted space within a fragmented LOB segment, |
-- | use the following SQL command: |
-- | |
-- | ALTER TABLE <OWNER>.<TABLE_NAME> MODIFY LOB (<LOB_COLUMN>) (SHRINK SPACE);
-- | |
-- | NOTE: The time required to shrink the LOB segment is a function |
-- | of how much data needs to be coalesced. In many cases, |
-- | the shrink operation can take minutes or possibly several |
-- | hours depending on the amount of data that needs to be |
-- | moved. |
-- | |
-- | NOTE : As with any code, ensure to test this script in a development |
-- | environment before attempting to run it in production. |
-- +----------------------------------------------------------------------------+
SET TERMOUT OFF;
COLUMN current_instance NEW_VALUE current_instance NOPRINT;
COLUMN current_user NEW_VALUE current_user NOPRINT;
SELECT rpad(instance_name, 17) current_instance, rpad(user, 13) current_user FROM v$instance;
SET TERMOUT ON;
PROMPT
PROMPT +------------------------------------------------------------------------+
PROMPT | Report : LOB Fragmentation for the Current User |
PROMPT | Instance : ¤t_instance |
PROMPT | User : ¤t_user |
PROMPT +------------------------------------------------------------------------+
PROMPT
SET ECHO OFF
SET FEEDBACK 6
SET HEADING ON
SET LINESIZE 180
SET PAGESIZE 50000
SET TERMOUT ON
SET SERVEROUTPUT ON
SET TIMING OFF
SET TRIMOUT ON
SET TRIMSPOOL ON
SET VERIFY OFF
CLEAR COLUMNS
CLEAR BREAKS
CLEAR COMPUTES
declare
v_actual_length number;
v_allocated_length number;
v_lob_fragmentation_pct number;
v_actual_length_char varchar2(50);
v_allocated_length_char varchar2(50);
v_statement varchar2(2000);
v_table_column_pad_length constant number := 45;
v_actual_length_pad_length constant number := 20;
v_allocated_length_pad_length constant number := 20;
v_fragmentation_pad_length constant number := 15;
begin
dbms_output.enable(1000000);
-- Print column headers
dbms_output.put_line( rpad('LOB COLUMN - [OWNER.TABLE.COLUMN]', v_table_column_pad_length) || ' ' ||
lpad('ALLOCATED LOB LENGTH', v_allocated_length_pad_length) || ' ' ||
lpad('ACTUAL LOB LENGTH', v_actual_length_pad_length) || ' ' ||
lpad('FRAGMENTATION', v_fragmentation_pad_length)
);
dbms_output.put_line( rpad('-', v_table_column_pad_length, '-') || ' ' ||
lpad('-', v_allocated_length_pad_length, '-') || ' ' ||
lpad('-', v_actual_length_pad_length, '-') || ' ' ||
lpad('-', v_fragmentation_pad_length, '-')
);
-- Get all LOB segments for the current user
for v_lob_segment in (select user, l.table_name, l.column_name
from user_lobs l join user_segments s
using (segment_name, tablespace_name)
where l.column_name not like '"%'
order by 2,3)
loop
dbms_output.put(rpad(v_lob_segment.user || '.' || v_lob_segment.table_name || '.' || v_lob_segment.column_name, v_table_column_pad_length));
dbms_output.put(' ');
-- Get "allocated size" of the LOB segment
v_statement := 'begin '
|| 'select to_char(a.bytes, ''999,999,999,999,999'') '
|| 'into :col_val2 '
|| 'from user_segments a join user_lobs b '
|| 'using (segment_name) '
|| 'where b.table_name = ''' || v_lob_segment.table_name || ''''
|| ' and b.column_name = ''' || v_lob_segment.column_name || ''';'
|| 'end;';
execute immediate v_statement using out v_allocated_length_char;
v_allocated_length_char := regexp_replace(v_allocated_length_char, ' ', '');
v_allocated_length := regexp_replace(v_allocated_length_char, ',', '');
dbms_output.put(lpad(v_allocated_length_char, v_allocated_length_pad_length));
dbms_output.put(' ');
begin
-- Get "actual size" of the LOB segment
v_statement := 'begin '
|| 'select to_char(sum(dbms_lob.getlength(' || v_lob_segment.column_name || ')), ''999,999,999,999,999'' ) '
|| 'into :col_val1 '
|| 'from ' || v_lob_segment.table_name || ';'
|| 'end;';
execute immediate v_statement using out v_actual_length_char;
v_actual_length_char := nvl(regexp_replace(v_actual_length_char, ' ', ''), '0');
v_actual_length := nvl(regexp_replace(v_actual_length_char, ',', ''), 0);
dbms_output.put(lpad(v_actual_length_char, v_actual_length_pad_length));
dbms_output.put(' ');
-- Calculate LOB fragmentation
if v_actual_length = 0 then
v_actual_length := v_allocated_length;
end if;
v_lob_fragmentation_pct := round(((1-(v_actual_length/v_allocated_length))*100), 2);
dbms_output.put(lpad(v_lob_fragmentation_pct || ' %', v_fragmentation_pad_length));
exception
when others then null;
end;
dbms_output.put_line('');
end loop;
end;
/
0 0
- Scripts:此脚本慎用lob_fragmentation_user.sql
- Scripts:根据sql_id创建sql_profile的脚本(此脚本要慎用)gps.sql
- Scripts:dump nclob列的脚本(慎用)lob_dump_nclob.sql
- Scripts:分析RAC hang的脚本(此脚本要慎用,在某些版本下可能会导致系统重启)RACDIAG.SQL
- Scripts:重新编译失效对象的脚本(生产环境慎用)dba_recompile_invalid_objects.sql
- Scripts:dump clob列内容的脚本(慎用)lob_dump_clob.sql
- Scripts:dump blob列内容的脚本(慎用)lob_dump_blob.sql
- Scripts:显示有LOB列的表的脚本(慎用)LobData.sql
- Scripts:从shared_pool中创建并删除profile的脚本(注意,此脚本危险比较高,生产环境不要使用)flush_sql10p.sql
- Scripts:数据库升级诊断脚本dbupgdiag.sql
- Scripts:列出用户信息的脚本sec_users.sql
- Scripts:重建索引的脚本(看懂脚本再用)rebuild_indx.sql
- Scripts:生成随机数的SQL脚本dba_random_number.sql
- Scripts:查看回滚的SQL的脚本 huigun.sql
- Scripts:查询等待事件的SQL脚本owi_event_names.sql
- Scripts:给出系统pid找出sql的脚本pid4sql.sql
- Scripts:查看未提交的事务的脚本CurrentActivity.sql
- Scripts:数据库巡检脚本for 8i dba_snapshot_database_8i.sql
- ZOJ-3056
- Iterator(迭代器)的一般用法
- java基础加强_代理
- FZU 2128 最长子串
- 为什么已经引用了using System.Management 使用ManagementObjectSearcher时为什么提示未引用空间?
- Scripts:此脚本慎用lob_fragmentation_user.sql
- Android中如何获取设备的宽高
- [ALGO-50] 数组查找及替换
- Permutations II
- Linux学习笔记2014-05-27
- LeetCode: Climbing Stairs [070]
- VmodCAM 初始化
- 结构体输入姓名,年龄,性别。你猜我写的对不对??
- J2EE学习篇之--Spring技术详解