Как узнать, фрагментирована ли таблица в Oracle? - PullRequest
2 голосов
/ 14 июня 2011

У меня есть стол, который, кажется, занимает больше места, чем нужно. Мне посоветовали скопировать данные в новую таблицу и переименовать новую таблицу и старую таблицу, чтобы поменять их местами. Как я могу подтвердить, что текущая таблица действительно фрагментирована? Как я могу оценить или рассчитать новый размер новой таблицы, содержащей те же данные?

Ответы [ 3 ]

2 голосов
/ 15 июня 2011

Если ваша статистика актуальна, это должно дать достойное указание, если в таблицах гораздо больше блоков, чем предполагает объем данных строк.

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

Это место будет использоваться для будущих вставок, поэтому не обязательно проблема. Если вы сделали большой архив или удалили данные, то может стоить того, чтобы освободить место (особенно если вы выполняете много полных операций сканирования таблицы). [Примечание: я предположил 8k блоков, которые по умолчанию.]

Если вы выполните CREATE / DROP / RENAME, вы потеряете все индексы, ограничения, гранты (плюс комментарии к таблицам, если вы их используете).

Вам лучше проверить текущее табличное пространство (смотрите USER_SEGMENTS) и выполнить ALTER TABLE tablename MOVE current_tablespace;

Вам также нужно будет перестроить индексы назад. Выберите их из USER_INDEXES и сделайте ALTER INDEX ... REBUILD;

0 голосов
/ 17 июня 2011

Попробуйте использовать dbms_space.space_usage и другие процедуры в пакете dbms_space.

0 голосов
/ 14 июня 2011

- Попробуйте запустить этот скрипт, используя svrmgrl, подключенный как 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;
/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...