On Nov 26, 3:32*pm, "Gerard H. Pille" <g... (AT) skynet (DOT) be> wrote:
Quote:
Volker Borchert wrote:
Shakespeare wrote:
Most times, these queries are generated by some tool that needs a where
clause anyway, and 'AND's or 'OR's the user specified clauses to it, and
they put in the 1=1 for when a user does not enter any condition..
Surprisingly, the optimizer sometimes seems to do a bad job about such
constant clauses. As in "where 1 = 2" resulting in a full table scan....
You're kidding, right? |
Volker is actually correct (OK, partially). However, it might be a
good idea to check the DBMS_XPLAN output and/or the output of a 10046
trace and/or the output of SET AUTOTRACE TRACEONLY STATISTICS. For
example, here is a test on Oracle 11.1.0.7 with a 100,000,000 row
table with a primary key column in a freshly bounced database:
SET AUTOTRACE TRACEONLY EXPLAIN
SELECT
*
FROM
T1
WHERE
1=2;
Execution Plan
----------------------------------------------------------
Plan hash value: 3332582666
---------------------------------------------------------------------------
Quote:
Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
Time |
|
---------------------------------------------------------------------------
Quote:
0 | SELECT STATEMENT | | 1 | 53 | 0
(0)| |
* 1 | FILTER | | | |
|
2 | TABLE ACCESS FULL| T1 | 100M| 5054M| 221K (1)|
00:44:14 |
|
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(NULL IS NOT NULL)
The plan indicates a full table scan, and the filter predicate?
Continuing:
SET AUTOTRACE TRACEONLY STATISTICS
ALTER SESSION SET TRACEFILE_IDENTIFIER = 'My_Trace';
ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT FOREVER, LEVEL 8';
SELECT
*
FROM
T1
WHERE
1=2;
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
0 consistent gets
0 physical reads
0 redo size
301 bytes sent via SQL*Net to client
349 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed
A full table scan on a 100,000,000 row table which performed 0
consistent gets.
SELECT SYSDATE FROM DUAL;
Now, a check of the 10046 trace file:
=====================
PARSING IN CURSOR #7 len=32 dep=0 uid=56 oct=3 lid=56 tim=327318181
hv=2373026659 ad='2775adb30' sqlid='077d50q6r30v3'
SELECT
*
FROM
T1
WHERE
1=2
END OF STMT
PARSE
#7:c=0,e=0,p=0,cr=0,cu=0,mis=1,r=0,dep=0,og=1,plh= 3332582666,tim=327318181
EXEC
#7:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh= 3332582666,tim=327318181
WAIT #7: nam='SQL*Net message to client' ela= 1 driver id=1413697536
#bytes=1 p3=0 obj#=527 tim=327322648
FETCH
#7:c=0,e=0,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh= 3332582666,tim=327318181
STAT #7 id=1 cnt=0 pid=0 pos=1 obj=0 op='FILTER (cr=0 pr=0pw=0
time=0 us)'
STAT #7 id=2 cnt=0 pid=1 pos=1 obj=68961 op='TABLE ACCESS FULL T1
(cr=0 pr=0 pw=0 time=0 us cost=221088 size=5300000000 card=100000000)'
WAIT #7: nam='SQL*Net message from client' ela= 11075 driver
id=1413697536 #bytes=1 p3=0 obj#=527 tim=327343489
The STAT lines in the 10046 trace also confirm that Oracle did not
even bother to execute the full table scan.
Just for confirmation:
SELECT
COUNT(*)
FROM
T1;
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
813324 consistent gets
813317 physical reads
0 redo size
342 bytes sent via SQL*Net to client
360 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
Charles Hooper
Co-author of "Expert Oracle Practices: Oracle Database Administration
from the Oak Table"
IT Manager/Oracle DBA
K&M Machine-Fabricating, Inc.