Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question.

Asked: April 19, 2010 - 2:25 pm UTC

Last updated: April 04, 2012 - 2:20 pm UTC

Version: 10.2

Viewed 10K+ times! This question is

You Asked

Hello Sir,


In a non-partition table when a row migration happen the original rowid point to the new location (i.e. forward pointer )
where the row resides, this way underlying indexes are uneffected (i.e. not invalidated)


what happen in partition table if partition key changes will underlying indexes (i.e. local or global) are invalidated ?


Thanks





and Tom said...

You have to enable row movement - either during table create time or via an ALTER TABLE <tname> enable row movement; command.


And then the rowid changes, internally we process the update of a partition key that causes the partition to change as a delete+insert (but we only fire an update trigger).


So, all indexes are naturally maintained - since we delete the row and then insert it into the new partition.

Rating

  (5 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

some more help

VS, May 25, 2010 - 9:06 am UTC

Dear Tom,
While I don't have doubts on the update trigger being executed by Oracle internally when a row moves from one partition to another.Is it possible to get this in some trace file using some trace event? I tried with 10046 level 12, but not able to make out which statement reflects this change.

could you please highlight the same,your help in this regard is much appreciated.

Regards,
VS
Tom Kyte
May 25, 2010 - 12:43 pm UTC

what doubts??

what are you looking for exactly? You update a row, we'll fire the update triggers but internally we'll delete the row and insert it


ops$tkyte%ORA10GR2> CREATE TABLE t
  2  (
  3    dt  date,
  4    x   int,
  5    y   varchar2(30)
  6  )
  7  enable row movement
  8  PARTITION BY RANGE (dt)
  9  (
 10    PARTITION part1 VALUES LESS THAN (to_date('01-jan-2008','dd-mon-yyyy')) ,
 11    PARTITION part2 VALUES LESS THAN (to_date('01-jan-2009','dd-mon-yyyy'))
 12  )
 13  /

Table created.

ops$tkyte%ORA10GR2> insert into t values ( to_date( '01-jun-2007', 'dd-mon-yyyy' ), 1, 'hello' );

1 row created.

ops$tkyte%ORA10GR2> create or replace trigger update_trigger
  2  after update on t for each row
  3  begin
  4          dbms_output.put_line( 'old key = ' || to_char( :old.dt, 'dd-mon-yyyy' ) ||
  5                                ' new key = ' || to_char( :new.dt, 'dd-mon-yyyy' ) );
  6          dbms_output.put_line( 'old rowid = ' || rowidtochar( :old.rowid ) ||
  7                                ' new rowid = ' || rowidtochar( :new.rowid ) );
  8  end;
  9  /

Trigger created.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> select 'part1', t.* from t partition(part1) union all select 'part2', t.* from t partition(part2);

'PART DT                 X Y
----- --------- ---------- ------------------------------
part1 01-JUN-07          1 hello

ops$tkyte%ORA10GR2> update t set dt = add_months(dt,12);
old key = 01-jun-2007 new key = 01-jun-2008
old rowid = AAA4GjAAEAAABNEAAA new rowid = AAA4GkAAEAAABNMAAA

1 row updated.

ops$tkyte%ORA10GR2> select 'part1', t.* from t partition(part1) union all select 'part2', t.* from t partition(part2);

'PART DT                 X Y
----- --------- ---------- ------------------------------
part2 01-JUN-08          1 hello



thanks for your response

VS, May 25, 2010 - 1:22 pm UTC

Dear Tom,

thanks for your response on this, what I am not able to get is :
"we'll fire the update triggers but internally we'll delete the row and insert it".

When I do a trace 10046 I am not able to see the delete and insert getting executed, is it possible to see these using some other even tracing?

Also if there 2 million rows that will be inserted first with null in the partitioning key and then during the course of processing the field be updated to some value resulting in row movement can we find out how much overhead that will be? as it will be 2 million inserts and deletes performed by the database.

Once again thanks for your help on this.

Regards,
VS
Tom Kyte
May 25, 2010 - 5:41 pm UTC

... am not able to see the delete and insert getting
executed, is it possible to see these using some other even tracing?

....

no, you won't- that is why I said "internally", we don't do sql at the lowest level of doing sql - we do calls to C subroutines way down there.


If you want to find out the "cost" of doing a 2 million row partition update - you should benchmark it - in a manner similar to what I did right above to show you the trigger firing. Set up your example, measure cpu, IO, response times, amount of redo generate, undo - etc...


I would probably NOT want to insert 2,000,000 records and then update them all causing them to be internally deleted and reinserted elsewhere. I'd like to insert them with the proper key in the first place if possible (much less work obviously)

Row Movement in partition table oracle 11gR2

Santosh, April 02, 2012 - 1:20 am UTC

Hi Tom,

As you said in above link, in partition too Oracle is doing Insert-Delete at way down in C subroutines.
So, I expect the performance in this case will be better than the conventional Insert-Delete operation.
But in this case, will it take care of fragmentation ? Or Still I have to do re-org or shrinking of main portion from where rows getting deleted ?

Tom Kyte
April 03, 2012 - 6:14 am UTC

define fragmentation for me.

As space is allocated/released in a block, the block will move off/on the freelist. When on the freelist - it will accept new inserts. When not on the freelist, it won't.

If the update that moves a row causes a block to have sufficient free space on it all of a sudden, the block will be on the freelist and will be available for the next insert into the table.

Row Movement in partition table oracle 11gR2

Santosh, April 04, 2012 - 1:23 pm UTC

Thanks Tom,

I mean, as rows will be deleted from main partition and getting added to other partition. if such row movement is too high say 40-50%. Then Do I need to do shrink on Main Partition? or Oracle will take care of it if I keep row movement enabled?
Tom Kyte
April 04, 2012 - 2:20 pm UTC

oracle will reuse that space, just like it reuses any space - yes.

There would be no need to shrink unless you never insert (or have rows moved) into that partition again.

Triggers on Specific Partitions

manu, July 02, 2014 - 12:28 pm UTC

Can we create trigger on a specific partiton of a Table? So say we have a table with 20 partitions and we move data only for 5 partitions and we need to tra-ck changes only to 5 specific partitions?
Also since the tables are large in size - Is trigger the right mechanism to capture those changes?

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library