Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Kolejność wykonania warunków w klauzuli SQL 'gdzie'

Czy jesteś pewny? „nie masz uprawnień”, aby zobaczyć plan egzekucji? A co z użyciem 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")

Jak widać, daje to dość dużo szczegółów na temat tego, jak zapytanie zostanie wykonane. Mówi mi, że:

  • warunek "emp.ename jak 'K%'" zostanie zastosowany jako pierwszy, podczas pełnego skanowania EMP
  • wtedy pasujące rekordy DEPT zostaną wybrane przez indeks na dept.deptno (za pomocą metody NESTED LOOPS)
  • w końcu zostanie zastosowany filtr „dept.loc, taki jak 'l%'.

Ta kolejność aplikacji nie ma nic wspólnego ze sposobem uporządkowania predykatów w klauzuli WHERE, co możemy pokazać w tym zapytaniu o zmienionej kolejności:

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")


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Przestaw Oracle z podzapytaniem

  2. Czy Oracle obsługuje wyszukiwanie pełnotekstowe?

  3. (+) =operator w Oracle sql, gdzie klauzula

  4. Czy możemy zaktualizować wartości klucza podstawowego tabeli?

  5. Korzystanie z Oracle JDeveloper 12c z Oracle Database 12c na platformie Oracle Cloud, część 3