tags:

views:

92

answers:

3

Which procedure is more performant for an update which affects zero rows?

UPDATE table SET column = value WHERE id = number;

IF SQL%Rowcount > 0 THEN
 COMMIT;
END IF;

or

UPDATE table SET column = value WHERE id = number;

COMMIT;

In other words if an Update affect ZERO rows and a commit is issued am I incurring any added expense at all?

I have a system which is being hampered by log file sync waits... and I'm wondering if issuing a commit; against a transaction which affects zero rows will write that statement to the log or not and thus cause more contention on LGWR.

+3  A: 

COMMIT does force the log file sync so the system will have to wait indeed.

However, ROLLBACK does too and at some time either of them will have to happen.

So if you issue neither COMMIT nor ROLLBACK, you are just staying with an open transaction which sooner or later will cause a log sync wait.

Probably, you want to batch you UPDATE operations rather than waiting for a first successful update and committing it.

Quassnoi
If the update doesn't affect any rows I don't think it will open a transaction. Updates that affect no rows don't show up in v$transaction (Although maybe there's more to it than that?) I think this means that there's no need for a commit or a rollback. From some simple testing it appears that avoiding the commit is about twice as fast. But either way the time to perform tens of thousands of these operations is less than a second. (Although maybe meaningless commits become more expensive when there are other sessions doing a lot of work?)
jonearles
@jonearles: yes it does open the transaction and it does show up in `v$transaction`.
Quassnoi
It doesn't show up in v$transaction for me on 10.2.0.1.0 (XE), although dbms_transaction.local_transaction_id() returns a non-null value. According to the docs both of them should show the active transaction(s). Here are my commands and results, do you get something different for v$transaction? (not including other sessions)create table update_test(id number, test1 varchar2(100)); [Table created.]update update_test set test1 = 'asdf' where id = 12345; [0 rows updated.]select count(*) from v$transaction; [0]select dbms_transaction.local_transaction_id() from dual; [10.35.8322]
jonearles
@jonearles: I see a record in `v$transaction` too.
Quassnoi
So EVERY DML statement opens a transaction that has to be closed by commit or rollback. An insert from a select that returns no rows or a delete or update with a where clause that doesn't delete/change any rows will all require an eventual commit or update. In most cases I tell people never check first, let the database tell you... i.o.w. don't check if you'll break a PK before inserting, just trap the error for the ones who do. In these cases it's the opposite... check if your update will affect rows because if it doesn't you'll be opening a needless transaction.
Stephanie Page
+3  A: 

There are risks in this. Technically while the UPDATE may affect zero rows, it can fire before or after update triggers on the table (not at row level). Those triggers could potentially "do something" that requires a commit/rollback.

Safer to check to see if LOCAL_TRANSACTION_ID is set.

Gary
This is true and good advice although it doesn't answer the question. I upvoted it for the advice but gave the answer to the actual 'answer' to the question.
Stephanie Page
A: 

There are any number of reasons which can underlie waits for log file sync. It seems unlikely that the main culprit is committing SQL statements which have updated zero rows. It is true that issuing too many commits can be the cause of this problem. For instance, if the application is set up to commit after every statement (e.g. by using AUTOCOMMIT=TRUE) instead of designing proper transactions. If this is the cause then there is not much you can do, short of a major rewrite of the application.

If you want to delve deeper into the root causes of your problem I recommend you read this exhaustive (and exhausting) article by Pythian's Riyaj Shamsudeen on Tuning ‘log file sync’ Event Waits.

APC
I never said that, "the main culprit is committing SQL statements which have updated zero rows". This would be my solution though. An alternative short of "a major rewrite of the application".
Stephanie Page
This doesn't attempt to answer the question. You're guessing at the problem instead.
Stephanie Page
@StephaniePage - actually I deliberately wasn't attempting to guess the problem. I thought your question was really about the causes of LOG FILE SYNC waits but apparently I was wrong. My bad.
APC