Форум OlegON > Компьютеры и Программное обеспечение > Операционные системы и программное обеспечение > Oracle

Как определить наличие сжатых блоков в таблице : Oracle

12.12.2024 11:37


21.10.2024 13:16
В настоящее время достаточно сыро выглядит работа со сжатием таблиц, по крайней мере я не смог найти нормально работающее средство для определения таблиц, где есть сжатые блоки. Эти блоки много чему могут препятствовать, например, не давать проходу 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 версии, прошу поделиться.
22.10.2024 19:04
В общем, обманулся я... На 11g сделал тестовую табличку, внес данные, шринк работает, скрипт выше дает NOCOMPRESS, сделал move compress, шринк не работает, скрипт выдает по прежнему NOCOMPRESS... Может, табличка маленькая, правда... Но факт остается фактом... Будем искать...
22.10.2024 19:08
Не выдержала душа поэта, добил табличку до 2к строк, и они все же стали COMP_FOR_OLTP

Код:
SQL> set timing on
SQL> r
  1  SELECT distinct CASE DBMS_COMPRESSION.get_compression_type ('SYS', 'BOBO', rowid)
  2	     WHEN 1  THEN 'COMP_NOCOMPRESS'
  3	     WHEN 2  THEN 'COMP_FOR_OLTP'
  4	     WHEN 4  THEN 'COMP_FOR_QUERY_HIGH'
  5	     WHEN 8  THEN 'COMP_FOR_QUERY_LOW'
  6	     WHEN 16 THEN 'COMP_FOR_ARCHIVE_HIGH'
  7	     WHEN 32 THEN 'COMP_FOR_ARCHIVE_LOW'
  8	     WHEN 64 THEN 'COMP_BLOCK'
  9	   END AS compression_type
 10* FROM  bobo

COMPRESSION_TYPE
---------------------------------------------------------------
COMP_FOR_OLTP

Elapsed: 00:00:20.84

SQL> select count(*) from bobo;

  COUNT(*)
----------
      2715
21 секунду на повторном проходе на 2715 записях... проц шустрый, то есть при миллионах записей это будет работать часа три... Совсем не смешно.
Часовой пояс GMT +3, время: 11:37.

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.