Quantcast
Channel: Deiby Gomez's Activities
Viewing all articles
Browse latest Browse all 108

Oracle Internals: Adding a column with default value

$
0
0

For this example I will use the following table:

SQL> create table dgomez.t1 (id number, value varchar2(20)) tablespace tbs1;

Table created.

Let's insert 2 rows:

SQL> insert into dgomez.t1 values (1,'deiby');

1 row created.

SQL> insert into dgomez.t1 values (2,'mauricio');

1 row created.

SQL> commit;

Commit complete.

Now, I will show you how the table block looks:

data_block_dump,data header at 0x7fde229bc064
===============
tsiz: 0x1f98
hsiz: 0x16
pbl: 0x7fde229bc064
76543210
flag=--------
ntab=1
nrow=2
frre=-1
fsbo=0x16
fseo=0x1f7d
avsp=0x1f67
tosp=0x1f67
0xe:pti[0] nrow=2 offs=0
0x12:pri[0] offs=0x1f8c
0x14:pri[1] offs=0x1f7d
block_row_dump:
tab 0, row 0, @0x1f8c
tl: 12 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02<<----1
col 1: [ 5] 64 65 69 62 79<<----Deiby
tab 0, row 1, @0x1f7d
tl: 15 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 03<<----2
col 1: [ 8] 6d 61 75 72 69 63 69 6f<<----Mauricio
end_of_block_dump

Now, I will alter the table adding a column with default value specifying "not null":

SQL> alter table dgomez.t1 add value2 varchar2(20) default 'oraworld' not null;

Table altered.

Let's see how Oracle managed this DDL internally:

data_block_dump,data header at 0x7fde229bc064
===============
tsiz: 0x1f98
hsiz: 0x16
pbl: 0x7fde229bc064
76543210
flag=--------
ntab=1
nrow=2
frre=-1
fsbo=0x16
fseo=0x1f7d
avsp=0x1f67
tosp=0x1f67
0xe:pti[0] nrow=2 offs=0
0x12:pri[0] offs=0x1f8c
0x14:pri[1] offs=0x1f7d
block_row_dump:
tab 0, row 0, @0x1f8c<<--- The row has only 2 columns physically. 
tl: 12 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02<<----1
col 1: [ 5] 64 65 69 62 79<<----Deiby
tab 0, row 1, @0x1f7d<<--- The row has only 2 columns physically. 
tl: 15 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 03<<----2
col 1: [ 8] 6d 61 75 72 69 63 69 6f<<----Mauricio
end_of_block_dump

As you can see the default value 'oraworld' wasn't inserted in the new column in the rows already created. Why? Because Oracle store the default value in the dictionary, let me show you:

SQL> select table_name, column_name, data_default from dba_tab_columns where table_name='T1'

TABLE_NAME COLUMN_NAME DATA_DEFAULT
---------- ----------- --------------------
T1          ID
T1          VALUE
T1          VALUE2          'oraworld'

Whenever Oracle needs the value in that column, it only review the dictionary and return the default data. Using this feature of Oracle Database you will be able to alter any table adding a column with a default value in seconds regardless the table size. Even if the table has 1TB of data the alter table will last seconds.

I will insert another row with a non-default value and let's check if the rows already created get any change:

SQL> insert into dgomez.t1 values (3,'robles','nodefault');
SQL> commit;

data_block_dump,data header at 0x7fde229bc064
===============
tsiz: 0x1f98
hsiz: 0x18
pbl: 0x7fde229bc064
76543210
flag=--------
ntab=1
nrow=3
frre=-1
fsbo=0x18
fseo=0x1f66
avsp=0x1f4e
tosp=0x1f4e
0xe:pti[0] nrow=3 offs=0
0x12:pri[0] offs=0x1f8c
0x14:pri[1] offs=0x1f7d
0x16:pri[2] offs=0x1f66
block_row_dump:
tab 0, row 0, @0x1f8c<<-- Row didn't have any change.
tl: 12 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [ 5] 64 65 69 62 79
tab 0, row 1, @0x1f7d<<-- Row didn't have any change.
tl: 15 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 03
col 1: [ 8] 6d 61 75 72 69 63 69 6f
tab 0, row 2, @0x1f66
tl: 23 fb: --H-FL-- lb: 0x2 cc: 3
col 0: [ 2] c1 04
col 1: [ 6] 72 6f 62 6c 65 73
col 2: [ 9] 6e 6f 64 65 66 61 75 6c 74<<---Non Default Value
end_of_block_dump

As you can see the rows already created weren't modified and the default value is stored physically only for new rows.

What happen with the upcoming rows?

SQL> insert into dgomez.t1 (id, value) values (4,'robles');
SQL> insert into dgomez.t1 (id, value) values (5,'jose');

Now we will see the Table Block and you will see that for all the new rows the value in the new column has the the data physically stored:

data_block_dump,data header at 0x7fde229bc064
===============
tsiz: 0x1f98
hsiz: 0x1c
pbl: 0x7fde229bc064
76543210
flag=--------
ntab=1
nrow=5
frre=-1
fsbo=0x1c
fseo=0x1f3c
avsp=0x1f20
tosp=0x1f20
0xe:pti[0] nrow=5 offs=0
0x12:pri[0] offs=0x1f8c
0x14:pri[1] offs=0x1f7d
0x16:pri[2] offs=0x1f66
0x18:pri[3] offs=0x1f50
0x1a:pri[4] offs=0x1f3c
block_row_dump:
tab 0, row 0, @0x1f8c
tl: 12 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 02
col 1: [ 5] 64 65 69 62 79
tab 0, row 1, @0x1f7d
tl: 15 fb: --H-FL-- lb: 0x0 cc: 2
col 0: [ 2] c1 03
col 1: [ 8] 6d 61 75 72 69 63 69 6f
tab 0, row 2, @0x1f66
tl: 23 fb: --H-FL-- lb: 0x0 cc: 3
col 0: [ 2] c1 04
col 1: [ 6] 72 6f 62 6c 65 73
col 2: [ 9] 6e 6f 64 65 66 61 75 6c 74
tab 0, row 3, @0x1f50
tl: 22 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [ 2] c1 05
col 1: [ 6] 72 6f 62 6c 65 73
col 2: [ 8] 6f 72 61 77 6f 72 6c 64<<--- default value inserted physically
tab 0, row 4, @0x1f3c
tl: 20 fb: --H-FL-- lb: 0x2 cc: 3
col 0: [ 2] c1 06
col 1: [ 4] 6a 6f 73 65
col 2: [ 8] 6f 72 61 77 6f 72 6c 64<<--- default value inserted physically
end_of_block_dump

Be carefully with "no null"

When you don't specify "not null" in the "alter table add column" with default value, the default value is inserted physically for all the rows already created:

SQL> drop table dgomez.t1 purge;
SQL> create table dgomez.t1 (id number, value varchar2(20)) tablespace tbs1;
SQL> insert into dgomez.t1 values (1,'deiby');
SQL> insert into dgomez.t1 values (2,'mauricio');
SQL> commit;

I will alter the table adding a column with default value but without specify "not null":

SQL> alter table dgomez.t1 add value2 varchar2(20) default 'oraworld';

Table altered.

Let me show you the table block:

data_block_dump,data header at 0x7fde229bc064
===============
tsiz: 0x1f98
hsiz: 0x16
pbl: 0x7fde229bc064
76543210
flag=--------
ntab=1
nrow=2
frre=-1
fsbo=0x16
fseo=0x1f50
avsp=0x1f55
tosp=0x1f55
0xe:pti[0] nrow=2 offs=0
0x12:pri[0] offs=0x1f68
0x14:pri[1] offs=0x1f50
block_row_dump:
tab 0, row 0, @0x1f68
tl: 21 fb: --H-FL-- lb: 0x2 cc: 3
col 0: [ 2] c1 02
col 1: [ 5] 64 65 69 62 79
col 2: [ 8] 6f 72 61 77 6f 72 6c 64<<--Default value inserted for all rows
tab 0, row 1, @0x1f50
tl: 24 fb: --H-FL-- lb: 0x2 cc: 3
col 0: [ 2] c1 03
col 1: [ 8] 6d 61 75 72 69 63 69 6f
col 2: [ 8] 6f 72 61 77 6f 72 6c 64<<--Default value inserted for all rows
end_of_block_dump

So, be carefully because if your table has 1TB of data, can you imagine how long the "alter table add column" will last?

More articles about this feature: 

Otimização de comandos DDL - Portuguese, Dr. Mohamed Houri (ACE) and Alex Zaballa (ACE, OCM)
Optimización de operaciones DDL - Spanish, Dr. Mohamed Houri (ACE) and Deiby Gómez (ACE)

Follow me:

      


Viewing all articles
Browse latest Browse all 108

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>