Execution order of conditions in SQL 'where' clause

后端 未结 6 1380
温柔的废话
温柔的废话 2020-12-06 05:31

I have a set of conditions in my where clause like

WHERE 
d.attribute3 = \'abcd*\'  
AND x.STATUS != \'P\' 
AND x.STATUS != \'J\' 
AND x.STATUS != \'X\' 
AND         


        
6条回答
  •  时光说笑
    2020-12-06 06:25

    Are you sure you "don't have the authority" to see an execution plan? What about using AUTOTRACE?

    SQL> set autotrace on
    SQL> select * from emp
      2  join dept on dept.deptno = emp.deptno
      3  where emp.ename like 'K%'
      4  and dept.loc like 'l%'
      5  /
    
    no rows selected
    
    
    Execution Plan
    ----------------------------------------------------------
    
    ----------------------------------------------------------------------------------
    | Id  | Operation                    | Name         | Rows  | Bytes | Cost (%CPU)|
    ----------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT             |              |     1 |    62 |     4   (0)|
    |   1 |  NESTED LOOPS                |              |     1 |    62 |     4   (0)|
    |*  2 |   TABLE ACCESS FULL          | EMP          |     1 |    42 |     3   (0)|
    |*  3 |   TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)|
    |*  4 |    INDEX UNIQUE SCAN         | SYS_C0042912 |     1 |       |     0   (0)|
    ----------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - filter("EMP"."ENAME" LIKE 'K%' AND "EMP"."DEPTNO" IS NOT NULL)
       3 - filter("DEPT"."LOC" LIKE 'l%')
       4 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")
    

    As you can see, that gives quite a lot of detail about how the query will be executed. It tells me that:

    • the condition "emp.ename like 'K%'" will be applied first, on the full scan of EMP
    • then the matching DEPT records will be selected via the index on dept.deptno (via the NESTED LOOPS method)
    • finally the filter "dept.loc like 'l%' will be applied.

    This order of application has nothing to do with the way the predicates are ordered in the WHERE clause, as we can show with this re-ordered query:

    SQL> select * from emp
      2  join dept on dept.deptno = emp.deptno
      3  where dept.loc like 'l%'
      4  and emp.ename like 'K%';
    
    no rows selected
    
    
    Execution Plan
    ----------------------------------------------------------
    
    ----------------------------------------------------------------------------------
    | Id  | Operation                    | Name         | Rows  | Bytes | Cost (%CPU)|
    ----------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT             |              |     1 |    62 |     4   (0)|
    |   1 |  NESTED LOOPS                |              |     1 |    62 |     4   (0)|
    |*  2 |   TABLE ACCESS FULL          | EMP          |     1 |    42 |     3   (0)|
    |*  3 |   TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)|
    |*  4 |    INDEX UNIQUE SCAN         | SYS_C0042912 |     1 |       |     0   (0)|
    ----------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - filter("EMP"."ENAME" LIKE 'K%' AND "EMP"."DEPTNO" IS NOT NULL)
       3 - filter("DEPT"."LOC" LIKE 'l%')
       4 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")
    

提交回复
热议问题