Как я узнаю, фрагментирован ли таблица в Oracle?
-
27-10-2019 - |
Вопрос
У меня есть стол, который, кажется, занимает больше места, чем нужно. Мне посоветовали скопировать данные в новую таблицу и переименовать новую таблицу и старую таблицу, чтобы поменять их. Как я могу подтвердить, действительно ли текущая таблица фрагментирована? Как я могу оценить или рассчитать новый размер свежей таблицы, содержащей те же данные?
Решение
Если ваша статистика обновлена, это должно дать достойное указание, если таблицы имеют гораздо больше блоков, чем предполагает объем данных строки.
select table_name, round((num_rows * avg_row_len) /(8*1024)), blocks
from user_tables where ....
Это пространство будет использовано для будущих вставок, поэтому не обязательно проблема. Если вы сделали большой архив или удаление данных, это май Стоит восстановить пространство (особенно, если вы делаете много полного сканирования стола). [Примечание: я принял 8K -блоки, которые являются дефолтом.
Если вы выполняете создание/брось/переименование, вы потеряете какие -либо индексы, ограничения, гранты (плюс комментирование таблицы, если вы их используете).
Вам лучше проверить текущее табличное пространство (посмотрите на user_segments) и выполнять ALTER TABLE tablename MOVE current_tablespace;
Вам также нужно будет восстановить индексы на AFTWARDS. Выберите их из user_indexes и сделайте ALTER INDEX ... REBUILD;
Другие советы
- Попробуйте запустить этот скрипт, используя 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;
/
Рассмотрим использованиеdbms_space.space_usage
и другие процедуры в dbms_space
упаковка.