Prior to Oracle 11g, when you add a column with not null constraint and with a default value, Oracle actually populates the value in all the rows of the table. All the rows, ouch! Imagine a multimillion-row table where the data will be updated several million times and how much redo and undo it will generate. In addition, it will also lock the table for the entire duration preventing DDLs. This caused a lot of consternation among users.But In Oracle 11g, this is handled different.
Ran the script in 9iR2, 10gR2 and 11gR1 and Tkprof show's the below results.
create table T nologging
as
select *
from all_objects;
alter session set timed_statistics=true;
alter session set events '10046 trace name context forever, level 16';
alter table T add grade varchar2(1) default 'x' not null;
Oracle - 9iR2
********************************************************************************
alter table t add grade varchar2(1) default 'x' not null
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.01 0 0 0 0
Execute 0 0.00 0.00 0 0 0 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 1 0.00 0.01 0 0 0 0
Misses in library cache during parse: 1
Optimizer mode: CHOOSE
Parsing user id: 107
********************************************************************************
update "T" set "GRADE"='x'
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.22 0 0 0 0
Execute 1 1.35 1.95 452 459 33914 33243
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 1.35 2.18 452 459 33914 33243
Misses in library cache during parse: 1
Optimizer mode: CHOOSE
Parsing user id: 107 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
0 UPDATE
33243 TABLE ACCESS FULL T
********************************************************************************
Oracle -10gR2
********************************************************************************
alter table t add grade varchar2(1) default 'x' not null
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.01 0.04 0 0 0 0
Execute 1 0.01 0.30 0 1 2 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.03 0.35 0 1 2 0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 54
********************************************************************************
update "T" set "GRADE"='x'
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 1 0 0
Execute 1 3.21 5.51 548 2228 304319 56172
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 3.21 5.51 548 2229 304319 56172
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 54 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
0 UPDATE T (cr=1598 pr=95 pw=0 time=3176654 us)
159118 TABLE ACCESS FULL T (cr=2220 pr=548 pw=0 time=1113963 us)
********************************************************************************
Oracle - 11gR1
********************************************************************************
SQL ID : dpj1atuacv8zx
alter table t add grade varchar2(1) default 'x' not null
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 1 25 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.01 0 1 25 0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 81
********************************************************************************
looking at the 11g Trace File I could not see a reference to the UPDATE T...Statement This behavior results in significantly less redo and undo, and also completes faster.
Which version of 11g? I see in 11gR1.
ReplyDeleteupdate "DUMMY_TAB" set "PRIORITY_GROUP"=1
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 1 0 0
Execute 1 128.98 169.06 79978 109961 4075558 1973227
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 128.99 169.06 79978 109962 4075558 1973227
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 180 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
0 UPDATE DUMMY_TAB (cr=111092 pr=79978 pw=0 time=0 us)
1973227 PX COORDINATOR (cr=109874 pr=42226 pw=0 time=173927 us)
1973227 PX SEND QC (RANDOM) :TQ10000 (cr=109874 pr=42226 pw=0 time=154567 us cost=8337 size=21636615 card=1664355)
1973227 PX BLOCK ITERATOR (cr=109874 pr=42226 pw=0 time=142461 us cost=8337 size=21636615 card=1664355)
1973227 TABLE ACCESS FULL DUMMY_TAB (cr=109874 pr=42226 pw=0 time=128779 us cost=8337 size=21636615 card=1664355)
********************************************************************************
@Anonymous
ReplyDeleteI tried this in 11.1.0.6.0. Here is the Test case.
create table T
as
select *
from emp;
alter table T add y number default 5 not null;
When I ran this in 10GR2 database, It shows me this. ( ALTER statement and then UPDATE )
alter table T add y number default 5 not null
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.01 0.04 0 1 2 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.01 0.04 0 1 2 0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 100
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
log file sync 1 0.01 0.01
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 0.00 0.00
update "T" set "Y"=5
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 1 0 0
Execute 1 0.00 0.00 0 3 15 14
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.00 0 4 15 14
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 100 (recursive depth: 1)
Rows Row Source Operation
------- ---------------------------------------------------
0 UPDATE T (cr=3 pr=0 pw=0 time=341 us)
14 TABLE ACCESS FULL T (cr=3 pr=0 pw=0 time=67 us)
But in 11GR1, I see only ALTER and **NO** UPDATE statement.
alter table T add y number default 5 not null
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.03 0 0 0 0
Execute 1 0.00 0.09 0 3 26 0
Fetch 0 0.00 0.00 0 0 0 0
------- ------ -------- ---------- ---------- ---------- ---------- ----------
total 2 0.00 0.13 0 3 26 0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 91
Elapsed times include waiting on following events:
Event waited on Times Max. Wait Total Waited
---------------------------------------- Waited ---------- ------------
log file sync 1 0.00 0.00
SQL*Net message to client 1 0.00 0.00
SQL*Net message from client 1 0.00 0.00
Can you rerun this testcase as such and report me back?
create table T
as
select *
from emp;
alter table T add y number default 5 not null;
Hi Rajesh,
ReplyDeleteThanks for your prompt response.
You could be right with 11.1.0.6. But I don't have any of the versions that you mentioned and I have only 11.1.0.7 with lots of patches.
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
PL/SQL Release 11.1.0.7.0 - Production
CORE 11.1.0.7.0 Production
TNS for Linux: Version 11.1.0.7.0 - Production
NLSRTL Version 11.1.0.7.0 - Production
See if you can test it with this version.
Thanks anyway and I believe you. Just I want to know which version it's working, as this is very nice feature to have.
I figured out the issue. It's because of the blob column.
ReplyDelete