深入理解Oracle表(1):ORDERED和USE_NL

 

 

深入理解Oracle表(1):ORDERED和USE_NL

 

http://blog.csdn.net/linwaterbin/article/details/8544436

       ORDERED好理解,就是表示根據 from 後面表的順序join,從左到右,左邊的表做驅動表
       use_nl(t1,t2):表示對錶t1、t2關聯時採用嵌套循環連接,其並不能讓優化器確定誰是驅動表或誰是被驅動的表
       USE_NL(),先看看oracle doc怎麼說:
       
       In this statement, the USE_NL hint explicitly chooses a nested loops join with the customers table as the inner table:
       SELECT /*+ ORDERED USE_NL(customers) to get first row faster */
       accounts.balance, customers.last_name, customers.first_name
       FROM accounts, customers
       WHERE accounts.customer_id = customers.customer_id;
     
       customers 作爲inner table,也就是說作爲被驅動表。驅動表稱爲outer table
       如果指定的表是outer table(驅動表),則優化器會忽略這個hint
       如果非要強制它作爲inner table,可以配上ordered參數
       oradered 表示根據from 後面表的順序,從左到右join,左表做驅動表,3個或3個以上最有用
       也就是說use_nl如果只帶了一個表名作爲參數,則該表爲被驅動表
       如果帶了2個以上的參數,Oracle並沒有指出use_nl(a,b)中哪個是驅動表,所以常使用ordered或者full()或者index()來強化我們的目標
       

       以下是測試:


  1. hr@ORCL> select  first_name,departments.department_id from employees,departments where employees.department_id=departments.department_id;  
  2.   
  3. Execution Plan  
  4. ----------------------------------------------------------  
  5. Plan hash value: 169719308  
  6.   
  7. ---------------------------------------------------------------------------------  
  8. | Id  | Operation          | Name       | Rows  | Bytes | Cost (%CPU)| Time     |  
  9. ---------------------------------------------------------------------------------  
  10. |   0 | SELECT STATEMENT   |            |   106 |  1484 |     3   (0)| 00:00:01 |  
  11. |   1 |  NESTED LOOPS      |            |   106 |  1484 |     3   (0)| 00:00:01 |  
  12. |   2 |   TABLE ACCESS FULL| EMPLOYEES  |   107 |  1070 |     3   (0)| 00:00:01 |  
  13. |*  3 |   INDEX UNIQUE SCAN| DEPT_ID_PK |     1 |     4 |     0   (0)| 00:00:01 |  
  14. ---------------------------------------------------------------------------------  
hr@ORCL> select  first_name,departments.department_id from employees,departments where employees.department_id=departments.department_id;

Execution Plan
----------------------------------------------------------
Plan hash value: 169719308

---------------------------------------------------------------------------------
| Id  | Operation          | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |            |   106 |  1484 |     3   (0)| 00:00:01 |
|   1 |  NESTED LOOPS      |            |   106 |  1484 |     3   (0)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| EMPLOYEES  |   107 |  1070 |     3   (0)| 00:00:01 |
|*  3 |   INDEX UNIQUE SCAN| DEPT_ID_PK |     1 |     4 |     0   (0)| 00:00:01 |
---------------------------------------------------------------------------------

       此處優化器選擇employees作爲驅動表,因爲departments上有索引,而且索引正好建立在連接列上

  1. hr@ORCL> select /*+ use_nl(employees) */ first_name,departments.department_id from employees,departments where employees.department_id=departments.department_id;  
  2.   
  3. Execution Plan  
  4. ----------------------------------------------------------  
  5. Plan hash value: 169719308  
  6.   
  7. ---------------------------------------------------------------------------------  
  8. | Id  | Operation          | Name       | Rows  | Bytes | Cost (%CPU)| Time     |  
  9. ---------------------------------------------------------------------------------  
  10. |   0 | SELECT STATEMENT   |            |   106 |  1484 |     3   (0)| 00:00:01 |  
  11. |   1 |  NESTED LOOPS      |            |   106 |  1484 |     3   (0)| 00:00:01 |  
  12. |   2 |   TABLE ACCESS FULL| EMPLOYEES  |   107 |  1070 |     3   (0)| 00:00:01 |  
  13. |*  3 |   INDEX UNIQUE SCAN| DEPT_ID_PK |     1 |     4 |     0   (0)| 00:00:01 |  
  14. ---------------------------------------------------------------------------------  
hr@ORCL> select /*+ use_nl(employees) */ first_name,departments.department_id from employees,departments where employees.department_id=departments.department_id;

Execution Plan
----------------------------------------------------------
Plan hash value: 169719308

---------------------------------------------------------------------------------
| Id  | Operation          | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |            |   106 |  1484 |     3   (0)| 00:00:01 |
|   1 |  NESTED LOOPS      |            |   106 |  1484 |     3   (0)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| EMPLOYEES  |   107 |  1070 |     3   (0)| 00:00:01 |
|*  3 |   INDEX UNIQUE SCAN| DEPT_ID_PK |     1 |     4 |     0   (0)| 00:00:01 |
---------------------------------------------------------------------------------

       由於employees是作爲驅動表,優化器會忽略hint提示

  1. hr@ORCL> select /*+ ordered use_nl(employees) */ first_name,departments.department_id from departments,employees where employees.department_id=departments.department_id;  
  2.   
  3. Execution Plan  
  4. ----------------------------------------------------------  
  5. Plan hash value: 2677871237  
  6.   
  7. -------------------------------------------------------------------------------------------------  
  8. | Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |  
  9. -------------------------------------------------------------------------------------------------  
  10. |   0 | SELECT STATEMENT            |                   |   106 |  1484 |     8   (0)| 00:00:01 |  
  11. |   1 |  TABLE ACCESS BY INDEX ROWID| EMPLOYEES         |     4 |    40 |     1   (0)| 00:00:01 |  
  12. |   2 |   NESTED LOOPS              |                   |   106 |  1484 |     8   (0)| 00:00:01 |  
  13. |   3 |    INDEX FULL SCAN          | DEPT_ID_PK        |    27 |   108 |     1   (0)| 00:00:01 |  
  14. |*  4 |    INDEX RANGE SCAN         | EMP_DEPARTMENT_IX |    10 |       |     0   (0)| 00:00:01 |  
  15. -------------------------------------------------------------------------------------------------  
hr@ORCL> select /*+ ordered use_nl(employees) */ first_name,departments.department_id from departments,employees where employees.department_id=departments.department_id;

Execution Plan
----------------------------------------------------------
Plan hash value: 2677871237

-------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                   |   106 |  1484 |     8   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMPLOYEES         |     4 |    40 |     1   (0)| 00:00:01 |
|   2 |   NESTED LOOPS              |                   |   106 |  1484 |     8   (0)| 00:00:01 |
|   3 |    INDEX FULL SCAN          | DEPT_ID_PK        |    27 |   108 |     1   (0)| 00:00:01 |
|*  4 |    INDEX RANGE SCAN         | EMP_DEPARTMENT_IX |    10 |       |     0   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------

       現在是departments作爲驅動表了

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章