开发者

How do I know if a table in Oracle is fragmented?

开发者 https://www.devze.com 2023-03-13 01:40 出处:网络
I have a table which seems to be taking up more space than it needs to. I have been advised to copy the data to a new table and ren开发者_如何学JAVAame the new table and old table to swap them. How ca

I have a table which seems to be taking up more space than it needs to. I have been advised to copy the data to a new table and ren开发者_如何学JAVAame the new table and old table to swap them. How can I confirm if a current table is actually fragmented? How can I estimate or calculate the new size of the fresh table containing the same data?


If your stats are up to date, this should give a decent indication if tables have lots more blocks than the volume of row data suggests.

select table_name, round((num_rows * avg_row_len) /(8*1024)), blocks 
from user_tables where ....

This space would be used for future inserts, so isn't necessarily a problem. If you've done a large archive or delete of data, it may be worth reclaiming space (especially if you do lots of full table scans). [Note: I've assumed 8k blocks, which are the default.]

If you do a CREATE/DROP/RENAME you'll lose any indexes, constraints, grants (plus table comments if you use them).

You are better off checking the current tablespace (look in USER_SEGMENTS) and doing an ALTER TABLE tablename MOVE current_tablespace;

You will need to rebuild indexes aftwards too. Pick them from USER_INDEXES and do an ALTER INDEX ... REBUILD;


-- Try to run this script using svrmgrl connected as DBA

set serveroutput on

DECLARE
   libcac   NUMBER (6, 2);
   rowcac   NUMBER (6, 2);
   bufcac   NUMBER (6, 2);
   redlog   NUMBER (6, 2);
   spsize   NUMBER;
   blkbuf   NUMBER;
   logbuf   NUMBER;
BEGIN
   SELECT VALUE
     INTO redlog
     FROM v$sysstat
    WHERE name = 'redo log space requests';

   SELECT 100 * (SUM (pins) - SUM (reloads)) / SUM (pins)
     INTO libcac
     FROM v$librarycache;

   SELECT 100 * (SUM (gets) - SUM (getmisses)) / SUM (gets)
     INTO rowcac
     FROM v$rowcache;

   SELECT 100 * (cur.VALUE con.VALUE - phys.VALUE)/(cur.VALUE con.VALUE)
into bufcac
from v$sysstat cur,v$sysstat con,v$sysstat phys,
v$statname ncu,v$statname nco,v$statname nph
where cur.statistic# = ncu.statistic# and
ncu.name = 'db block gets' and
con.statistic# = nco.statistic# and
nco.name = 'consistent gets' and
phys.statistic# = nph.statistic# and
nph.name = 'physical reads';

select VALUE
into spsize
from v$parameter
where name = 'shared_pool_size';

select VALUE
into blkbuf
from v$parameter
where name = 'db_block_buffers';

select VALUE
into logbuf
from v$parameter
where name = 'log_buffer';

DBMS_OUTPUT.put_line('> SGA CACHE STATISTICS');
DBMS_OUTPUT.put_line('> ********************');
DBMS_OUTPUT.put_line('> SQL Cache Hit rate = '||libcac);
DBMS_OUTPUT.put_line('> Dict Cache Hit rate = '||rowcac);
DBMS_OUTPUT.put_line('> Buffer Cache Hit rate = '||bufcac);
DBMS_OUTPUT.put_line('> Redo Log space requests = '||redlog);
DBMS_OUTPUT.put_line('> ');
DBMS_OUTPUT.put_line('> INIT.ORA SETTING');
DBMS_OUTPUT.put_line('> ****************');
DBMS_OUTPUT.put_line('> Shared Pool Size = '||spsize||' Bytes');
DBMS_OUTPUT.put_line('> DB Block Buffer = '||blkbuf||' Blocks');
DBMS_OUTPUT.put_line('> Log Buffer = '||logbuf||' Bytes');
DBMS_OUTPUT.put_line('> ');

if libcac < 99
then
DBMS_OUTPUT.put_line('*** HINT: Library Cache too low! Increase the Shared Pool Size.');
end if;

if rowcac < 85
then
DBMS_OUTPUT.put_line('*** HINT: Row Cache too low! Increase the Shared Pool Size.');
end if;

if bufcac < 90
then
DBMS_OUTPUT.put_line('*** HINT: Buffer Cache too low! Increase the DB Block Buffer value.');
end if;

if redlog > 100
then
DBMS_OUTPUT.put_line('*** HINT: Log Buffer value is rather low!');
end if;

end;
/


Consider usingdbms_space.space_usage and other procedures in the dbms_space package.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号