Skip to Main Content

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Debasish.

Asked: January 04, 2016 - 12:38 pm UTC

Last updated: January 07, 2016 - 4:32 pm UTC

Version: oracle 11g

Viewed 10K+ times! This question is

You Asked

create or replace
PROCEDURE TABLE_UPDATE AS

CURSOR REC_CUR IS
SELECT ROWID FROM TEMP_TABLE where ROW_ID IS NULL AND NROW_ID IS NOT NULL;

TYPE ROWID_T IS TABLE OF VARCHAR2(50);

ROWID_TAB ROWID_T;
BEGIN
OPEN REC_CUR;
LOOP
FETCH REC_CUR BULK COLLECT INTO ROWID_TAB LIMIT 5000;
EXIT WHEN ROWID_TAB.COUNT() = 0;

FORALL I IN ROWID_TAB.FIRST .. ROWID_TAB.LAST
UPDATE /*+ PARALLEL(TEMP_TABLE 12) */ TEMP_TABLE NOLOGGING
SET NROW_ID = ROW_ID
WHERE ROWID = ROWID_TAB(I) AND ROW_ID IS NULL;
COMMIT;

END LOOP;
CLOSE REC_CUR;
END;

Against this above procedure one of our DBA make a comment as mentioned below :
"This update is based on 'rowid' column that is a hidden pseudo column, and not a part of the table definition. It access rows directly through OS layer that is highly I/O intensive process."

Please help whether this update statement can create any performance related problem.


and Chris said...

Rowids are the fastest way to access a single row:

https://oracle-base.com/articles/misc/rowids-for-plsql-performance

That said, your code selects and updates the same table. So it may be quicker to do the update in a single statement. From what I understand of the above, it looks like you can do:

update temp_table
set    nrow_id = rowid;


Though why you want to set a column to the rowid is beyond me!

Rating

  (2 ratings)

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

Comments

fast

A reader, January 04, 2016 - 4:33 pm UTC

Rowid is the fastest way to update a row or delete a row from a table.

To Chris

Rajeshwaran Jeyabal, January 07, 2016 - 1:22 pm UTC

That said, your code selects and updates the same table. So it may be quicker to do the update in a single statement. From what I understand of the above, it looks like you can do:

update temp_table
set nrow_id = rowid;
Though why you want to set a column to the rowid is beyond me!


looking into the initial code it is
....
FORALL I IN ROWID_TAB.FIRST .. ROWID_TAB.LAST 
UPDATE /*+ PARALLEL(TEMP_TABLE 12) */ TEMP_TABLE NOLOGGING 
SET NROW_ID = ROW_ID 
WHERE ROWID = ROWID_TAB(I) AND ROW_ID IS NULL; 
COMMIT; 
....

which says
1) for each ROWID available in the collection ROWID_TAB(I)
2) check if the corresponding row in table has ROW_ID as NULL
3) if yes then update table NROW_ID WITH ROW_ID (not ROWID)

so the update become this way

update temp_table
set nrow_id = row_id
where row_id is NULL;

or
update temp_table
set nrow_id = NULL
where row_id is NULL;

Chris Saxon
January 07, 2016 - 4:32 pm UTC

Yes, to match the original code you need to at the where clause. I'm still not sure why the poster wants to do this though.

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