Навигация
Главная »  Sql 

UNUSED COLUMNS и дисковое пространство


Источник: oracle
На написание этого небольшого материала автора подтолкнул очередной вопрос разработчиков о том, каково влияние операции SET UNUSED COLUMN на последующий расход дискового пространства. Вопрос вовсе не праздный, если учесть современные объемы данных и время, потребное для их реорганизации. Поэтому автор решил продемонстрировать, а что же собственно происходит, когда выполняется операция SET UNUSED COLUMN.

Начнем с того, что весьма распространено заблуждение, гласящее, что unused column удаляется из словаря данных. Разумеется, это не так, и существуют представления ..._TAB_COLS, позволяющие увидеть, что происходит с полями, помеченными как UNUSED.

SQL> CREATE TABLE table1(x int primary key);  Table created.  SQL> CREATE TABLE table2(x int, y int default 0, 2  constraint y_c1 primary key(y), 3  constraint y_c2 foreign key(y) references table1(x), 4  constraint y_c3 check (y > 0));  Table created.  SQL> col data_default format a10 SQL> col nullable format a10 SQL> col column_name format a30 SQL> col hidden_column format a10 SQL> select column_name, data_default, nullable, hidden_column 2  from user_tab_cols where table_name = 'TABLE2';  COLUMN_NAME                    DATA_DEFAU NULLABLE   HIDDEN_COL ------------------------------ ---------- ---------- ---------- X                                         Y          NO Y                              0          N          NO  SQL> select constraint_name, constraint_type from user_constraints 2  where table_name = 'TABLE2';  CONSTRAINT_NAME                C ------------------------------ - Y_C3                           C Y_C1                           P Y_C2                           R  SQL> alter table table2 set unused column y;  Table altered.  SQL> select column_name, data_default, nullable, hidden_column 2  from user_tab_cols where table_name = 'TABLE2';  COLUMN_NAME                    DATA_DEFAU NULLABLE   HIDDEN_COL ------------------------------ ---------- ---------- ---------- X                                         Y          NO SYS_C00002_09100918:16:50$                Y          YES  SQL> select constraint_name, constraint_type from user_constraints 2  where table_name = 'TABLE2';  no rows selected  
В-общем, этого можно было ожидать - Oracle переименовал колонку, присвоив ей сгенерированное системой имя, и - что существенно - отменил наложенное на нее ограничение NOT NULL и значение по умолчанию DEFAULT. Кроме того, исчезли все ограничения, связанные с этой колонкой - PRIMARY KEY, FOREIGN KEY и CHECK. Осталась скрытая от конечного пользователя колонка с системным именем, допускающая хранение NULL-величин и не имеющая значения по умолчанию. Логично предположить, что при операциях вставки это поле неявным образом будет учитываться при формировании физической записи внутри блока -несмотря на то, что разработчик более не имеет с ним дела явно. В противном случае Oracle потребовалось бы каким-то образом отличать "старые" записи - когда поле было еще "живым", от новых, когда поле уже "умерло". Этакий кот Шредингера внутри базы данных...

Давайте выполним несколько простых манипуляций и посмотрим на содержимое блока таблицы после их завершения.

SQL> CREATE TABLE T_EXP (x int, y varchar2(254)) 2  /  Table created.  SQL> insert into T_EXP values(1,'a');  1 row created.  SQL> commit;  Commit complete.  SQL> alter table t_EXP set unused column y;  Table altered.  SQL> insert into T_EXP values(2);  1 row created.  SQL> commit;  Commit complete.  SQL> alter table t_exp add (y varchar2(255));  Table altered.  SQL> insert into T_EXP values(3,'b');  1 row created.  SQL> commit;  Commit complete.  SQL> select distinct dbms_rowid.rowid_relative_fno(rowid) "file", 2  dbms_rowid.rowid_block_number(rowid) "block" 3  from T_exp;  file      block ---------- ---------- 9        599  SQL> alter system dump datafile 9 block 599;  System altered. 
Дамп блока содержит следующую информацию

tab 0, row 0, @0x1f90 tl: 8 fb: --H-FL-- lb: 0x0  cc: 2 col  0: [ 2]  c1 02 col  1: [ 1]  61 tab 0, row 1, @0x1f8a tl: 6 fb: --H-FL-- lb: 0x0  cc: 1 col  0: [ 2]  c1 03 tab 0, row 2, @0x1f81 tl: 9 fb: --H-FL-- lb: 0x1  cc: 3 col  0: [ 2]  c1 04 col  1: *NULL* col  2: [ 1]  62 
Итак, наши подозрения вполне подтвердились - поле, помеченное как unused ведет себя как самое обычное nullable - поле со значением по умолчанию NULL. И если это поле не является последним в словарном списке колонок таблицы (в соответствии со значением поля COLUMN_ID), то при внесении каждой новой записи или изменении старой оно будет добавлять 1 байт, содержащий значение 0xFF, к общему содержимому записи в блоке - при условии, если хотя бы одна колонка, следующая за ней, принимает значение, отличное от NULL.



 

 Немного про Deadlock.
 API PHP в JavaScript. Краткий обзор PHP.JS.
 Создание и удаление таблиц в MS SQL Server.
 Microsoft Project Central в управлении проектами.
 Зачем нужна ИТ-сертификация?.


Главная »  Sql 

© 2022 Team.Furia.Ru.
Частичное копирование материалов разрешено.