Уплотнение данных.

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

Уплотнение устоявшихся данных возможно из - за того, что при создании таблиц устанавливается параметр PCTFREE равный, например 10 %. Если на момент полного импорта данных установить PCTFREE =1, то данные уплотнятся на 9 % (а если были удаления данных, то и больше), что положительно скажется на скорости выборки данных, и при том же значении размера таблицы свободного места в ней будет больше. После импорта нужно восстановить старые значения PCTFREE.

Итак, по порядку:

  1. Создаём временную служебную таблицу с текущими значениями PCTFREE. Тут же можно исключить из списка все изменяющиеся таблицы, что бы потом не было мигрирующих строк.
  2. CREATE TABLE pct_free_tables as
    SELECT owner,table_name,pct_free
    FROM dba_tables
    WHERE owner NOT IN ('SYS','SYSTEM','TOAD');
  3. Непосредственно перед полным экспортом данных устанавливаем PCTFREE =1 для всех выбранных таблиц:
     DECLARE 
       v_cursor number;
       CURSOR c_tables is
       SELECT owner,table_name,pct_free FROM pct_free_tables;
     BEGIN
       v_cursor:=DBMS_SQL.open_cursor;
       FOR c_tbl IN c_tables LOOP
         BEGIN
           DBMS_SQL.parse(v_cursor,'alter table '||c_tbl.owner||'.'||c_tbl.table_name||
                          ' PCTFREE 1',dbms_sql.v7);
           DBMS_OUTPUT.PUT_LINE(c_tbl.owner||'.'||c_tbl.table_name);
         EXCEPTION WHEN OTHERS THEN
           DBMS_OUTPUT.PUT_LINE('ups..except on '||c_tbl.owner||'.'||c_tbl.table_name);
         END;
       END LOOP;
       DBMS_SQL.CLOSE_CURSOR(v_cursor);
     END; 
  4. После полного импорта данных восстанавливаем 'родные' значения PCTFREE :
    DECLARE 
      v_cursor number;
      CURSOR c_tables is
      SELECT owner,table_name,pct_free FROM pct_free_tables;
    BEGIN
      v_cursor:=DBMS_SQL.open_cursor;
      FOR c_tbl IN c_tables LOOP
        BEGIN
          DBMS_SQL.parse(v_cursor,'alter table '||c_tbl.owner||'.'||c_tbl.table_name||
                         ' PCTFREE '||c_tbl.pct_free,dbms_sql.v7);
          DBMS_OUTPUT.PUT_LINE(c_tbl.owner||'.'||c_tbl.table_name);
        EXCEPTION WHEN OTHERS THEN
          DBMS_OUTPUT.PUT_LINE('ups..except on '||c_tbl.owner||'.'||c_tbl.table_name);
        END;
      END LOOP;
      DBMS_SQL.CLOSE_CURSOR(v_cursor);
    END;
Хостинг от uCoz