I have a query to select users from a table, given user id. This parameter is optional.
This is the query:
SELECT * FROM USERS
WHERE (USER_ID = :USER_ID OR :USER_ID IS NULL)
ORDER BY USER_ID;
Now I execute the query finding one user, so :USER_ID takes the valor 1 :
SELECT * FROM USERS
WHERE (USER_ID = 1 OR 1 IS NULL)
ORDER BY USER_ID;
This query takes 5 seconds.
And then, I add to the previous query OR :USER_ID IS NULL many times. This example takes much more time than the first:
SELECT * FROM USERS
WHERE (USER_ID = 1 OR 1 IS NULL [OR 1 IS NULL]x100)
ORDER BY USER_ID;
This query takes 30 seconds.
The execution plan are the same in the two examples:
---------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |
---------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |  3256K|   695M|       |   682K  (1)| 00:00:27 |       |       |
|   1 |  SORT ORDER BY              |         |  3256K|   695M|   877M|   682K  (1)| 00:00:27 |       |       |
|   2 |   PARTITION RANGE ALL       |         |  3256K|   695M|       |   534K  (1)| 00:00:21 |     1 |1048575|
|*  3 |    TABLE ACCESS STORAGE FULL| USERS |  3256K|   695M|       |   534K  (1)| 00:00:21 |     1 |1048575|
Version of Oracle: Oracle Database 12c
Why oracle does not take the first statement, that it's always true, and stop evaluating the rest?
 
    