В настоящее время достаточно сыро выглядит работа со сжатием таблиц, по крайней мере я не смог найти нормально работающее средство для определения таблиц, где есть сжатые блоки. Эти блоки много чему могут препятствовать, например, не давать проходу shrink space. И вот, следим за руками.
Есть таблица SMSPEC, например, произвольно. Делаем ей COMPRESS и записываем несколько строк. В dba_tables у нее COMPRESSION=ENABLED, все, как задумано, пишем, пишем, данные сжимаются, после чего делаем ей NOCOMPRESS, в dba_tables у нее COMPRESSION=DISABLED, но записанные блоки-то остаются... И таких таблиц может быть много...
Пытался осознать, что с этим делать, в текущих версиях можно поковыряться с
SQL код:
SET SERVEROUTPUT ON
DECLARE
l_blkcnt_cmp PLS_INTEGER;
l_blkcnt_uncmp PLS_INTEGER;
l_row_cmp PLS_INTEGER;
l_row_uncmp PLS_INTEGER;
l_cmp_ratio NUMBER;
l_comptype_str VARCHAR2(32767);
BEGIN
DBMS_COMPRESSION.get_compression_ratio (
scratchtbsname => upper('USERS_DATA'),
ownname => upper('SUPERMAG'),
objname => upper('SMSPEC'),
subobjname => NULL,
comptype => DBMS_COMPRESSION.COMP_QUERY_HIGH,
blkcnt_cmp => l_blkcnt_cmp,
blkcnt_uncmp => l_blkcnt_uncmp,
row_cmp => l_row_cmp,
row_uncmp => l_row_uncmp,
cmp_ratio => l_cmp_ratio,
comptype_str => l_comptype_str,
subset_numrows => DBMS_COMPRESSION.comp_ratio_allrows,
objtype => DBMS_COMPRESSION.objtype_table
);
DBMS_OUTPUT.put_line('Number of blocks used (compressed) : ' || l_blkcnt_cmp);
DBMS_OUTPUT.put_line('Number of blocks used (uncompressed) : ' || l_blkcnt_uncmp);
DBMS_OUTPUT.put_line('Number of rows in a block (compressed) : ' || l_row_cmp);
DBMS_OUTPUT.put_line('Number of rows in a block (uncompressed) : ' || l_row_uncmp);
DBMS_OUTPUT.put_line('Compression ratio : ' || l_cmp_ratio);
DBMS_OUTPUT.put_line('Compression type : ' || l_comptype_str);
END;
/
но, как я понял, крайне велик шанс налететь на баг, который не знаю, когда там поправили... Просто падает в параллельном процессе.
Еще один вариант сделать ход конем и попробовать так
SQL код:
DECLARE
v_owner VARCHAR2(30) := 'SUPERMAG';
v_table_name VARCHAR2(30);
v_count NUMBER;
v_sql VARCHAR2(1000);
v_compression PLS_INTEGER;
BEGIN
FOR table_rec IN (SELECT table_name
FROM dba_tables
WHERE owner = v_owner)
LOOP
v_sql := 'SELECT COUNT(*) FROM ' || v_owner || '.' || table_rec.table_name ||
' WHERE DBMS_COMPRESSION.get_compression_type(''' || v_owner || ''', ''' || table_rec.table_name || ''', rowid) != 1';
EXECUTE IMMEDIATE v_sql INTO v_count;
IF v_count > 0 THEN
DBMS_OUTPUT.PUT_LINE('Таблица: ' || v_owner || '.' || table_rec.table_name || ' имеет ' || v_count || ' строк без сжатия');
END IF;
END LOOP;
END;
/
работает настолько медленно, что можно сказать - вообще не работает...
Я так и не дождался результата
SQL код:
select count(*) from supermag.smspec where DBMS_COMPRESSION.get_compression_type ('SUPERMAG', 'SMSPEC', rowid)!=1;
суть вывода и значений можно понять по запросу
SQL код:
SELECT CASE DBMS_COMPRESSION.get_compression_type ('SUPERMAG', 'SMSPEC', rowid)
WHEN 1 THEN 'COMP_NOCOMPRESS'
WHEN 2 THEN 'COMP_FOR_OLTP'
WHEN 4 THEN 'COMP_FOR_QUERY_HIGH'
WHEN 8 THEN 'COMP_FOR_QUERY_LOW'
WHEN 16 THEN 'COMP_FOR_ARCHIVE_HIGH'
WHEN 32 THEN 'COMP_FOR_ARCHIVE_LOW'
WHEN 64 THEN 'COMP_BLOCK'
END AS compression_type
FROM supermag.smspec where rownum<10;
в общем и целом же задача пока выглядит нерешаемой... Если кто-то знает, что делать с этим счастьем на 11 версии, прошу поделиться.