Update xtab1 set xfield1='xxx' where xkey='123' and xfield1 <> 'xxx'
The filter predicate is applied before doing the update. So, I would go with option 2 and let Oracle do the job for you rather than doing it manually to first filter out the rows. Also, it would be an overhead to do it in two different steps. The filtering of rows should be a part of the same step.
Regarding the performance, I think indexes would play an important role.
You can test it and see:
Without index
Option 1
SQL> EXPLAIN PLAN FOR
2 UPDATE t SET sal = 9999 WHERE deptno = 20;
Explained.
SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 931696821
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 5 | 35 | 3 (0)| 00:00:01 |
| 1 | UPDATE | T | | | | |
|* 2 | TABLE ACCESS FULL| T | 5 | 35 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------
2 - filter("DEPTNO"=20)
14 rows selected.
SQL>
Option 2
SQL> EXPLAIN PLAN FOR
2 UPDATE t SET sal = 9999 WHERE deptno = 20 AND sal<>9999;
Explained.
SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 931696821
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 4 | 28 | 3 (0)| 00:00:01 |
| 1 | UPDATE | T | | | | |
|* 2 | TABLE ACCESS FULL| T | 4 | 28 | 3 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------
2 - filter("DEPTNO"=20 AND "SAL"<>9999)
14 rows selected.
With Index
SQL> CREATE INDEX t_idx ON t(deptno,sal);
Index created.
Option 1
SQL> EXPLAIN PLAN FOR
2 UPDATE t SET sal = 9999 WHERE deptno = 20;
Explained.
SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1175576152
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 5 | 35 | 1 (0)| 00:00:01 |
| 1 | UPDATE | T | | | | |
|* 2 | INDEX RANGE SCAN| T_IDX | 5 | 35 | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------
2 - access("DEPTNO"=20)
14 rows selected.
SQL>
Option 2
SQL> EXPLAIN PLAN FOR
2 UPDATE t SET sal = 9999 WHERE deptno = 20 AND sal<>9999;
Explained.
SQL>
SQL> SELECT * FROM TABLE(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1175576152
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 4 | 28 | 1 (0)| 00:00:01 |
| 1 | UPDATE | T | | | | |
|* 2 | INDEX RANGE SCAN| T_IDX | 4 | 28 | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------
2 - access("DEPTNO"=20)
filter("SAL"<>9999)
15 rows selected.
SQL>
So, in option 2 in all the cases, the filter("SAL"<>9999) is applied.