ITPub博客

首页 > Linux操作系统 > Linux操作系统 > rownum取值影响组合索引的使用

rownum取值影响组合索引的使用

原创 Linux操作系统 作者:wadekobe9 时间:2012-04-24 15:25:22 0 删除 编辑

创建一个组合索引,分别运行两个SQL,SQL唯一不同的地方是rownum<20rownum<200

create  index  IDX_TEL_ZU  on  t_s_Tel_Record(Employee_Id,Result)  online  nologging

--<例子1

SQL>  explain  plan  for 

    2   

    2    Select  *

    3        From  (Select  T0.*,  Rownum  As  Count_Id

    4                        From  (Select  Tel_Record_Id,

    5                                                  Employee_Id,

    6                                                  Customer_Id,

    7                                                  Callin_Number,

    8                                                  Calin_Time,

    9                                                  Recall_Number,

  10                                                  Extension,

  11                                                  Operation_Type,

  12                                                  Result,

  13                                                  Operator_Type_Id,

  14                                                  Operation_Desc

  15                                        From  t_s_Tel_Record

  16                                      Where  t_s_Tel_Record.Employee_Id  =  1067

  17                                          And  t_s_Tel_Record.Result  Is  Null

  18                                      Order  By  Tel_Record_Id  Desc)  T0

  19                      Where  Rownum  <=  20)  T1

  20      Where  Count_Id  >=  20  -  20  +  1;

 

Explained

 

SQL>  select  *  from  table(dbms_xplan.display);

 

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Plan hash value: 3591109256

----------------------------------------------------------------------------------------------------

| Id  | Operation                      | Name              | Rows  | Bytes | Cost (%CPU)| Time     |

----------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT               |                   |    20 | 43660 |  3174   (1)| 00:00:39 |

|*  1 |  VIEW                          |                   |    20 | 43660 |  3174   (1)| 00:00:39 |

|*  2 |   COUNT STOPKEY                |                   |       |       |            |          |

|   3 |    VIEW                        |                   |    21 | 45570 |  3174   (1)| 00:00:39 |

|*  4 |     TABLE ACCESS BY INDEX ROWID| T_S_TEL_RECORD    | 18844 |   993K|  3174   (1)| 00:00:39 |

|   5 |      INDEX FULL SCAN DESCENDING| PK_T_S_TEL_RECORD | 12173 |       |    12   (0)| 00:00:01 |

----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

   1 - filter("COUNT_ID">=1)

   2 - filter(ROWNUM<=20)

   4 - filter("T_S_TEL_RECORD"."EMPLOYEE_ID"=1067 AND "T_S_TEL_RECORD"."RESULT" IS NULL)

 

19 rows selected

 

上面没有走组合索引

 

=====================================================================

=====================================================================

下面改为200,走组合索引了

 

--<例子2

SQL> explain plan for

  2 

  2  Select *

  3    From (Select T0.*, Rownum As Count_Id

  4            From (Select /*+  index(t_s_Tel_Record IDX_TEL_ZU)*/

  5                         Tel_Record_Id,

  6                         Employee_Id,

  7                         Customer_Id,

  8                         Callin_Number,

  9                         Calin_Time,

 10                         Recall_Number,

 11                         Extension,

 12                         Operation_Type,

 13                         Result,

 14                         Operator_Type_Id,

 15                         Operation_Desc

 16                    From t_s_Tel_Record

 17                   Where t_s_Tel_Record.Employee_Id = 1067

 18                     And t_s_Tel_Record.Result Is Null

 19                  Order By Tel_Record_Id Desc

 20                   ) T0

 21           Where Rownum <= 200) T1

 22   Where Count_Id >= 20 - 20 + 1;

 

Explained

 

SQL> select * from table(dbms_xplan.display);

 

PLAN_TABLE_OUTPUT

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Plan hash value: 2274292752

----------------------------------------------------------------------------------------------------------

| Id | Operation            | Name      | Rows | Bytes |TempSpc| Cost (%CPU)| Time   |

----------------------------------------------------------------------------------------------------------

|  0 | SELECT STATEMENT        |        |  200 |  426K|    | 4043  (1)| 00:00:49 |

|* 1 | VIEW              |        |  200 |  426K|    | 4043  (1)| 00:00:49 |

|* 2 |  COUNT STOPKEY         |        |    |    |    |      |     |

|  3 |  VIEW             |        | 18844 |  38M|    | 4043  (1)| 00:00:49 |

|* 4 |   SORT ORDER BY STOPKEY    |        | 18844 |  993K| 2968K| 4043  (1)| 00:00:49 |

|  5 |   TABLE ACCESS BY INDEX ROWID| T_S_TEL_RECORD | 18844 |  993K|    | 3785  (1)| 00:00:46 |

|* 6 |    INDEX RANGE SCAN     | IDX_TEL_ZU   | 18844 |    |    |  17  (6)| 00:00:01 |

----------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

  1 - filter("COUNT_ID">=1)

  2 - filter(ROWNUM<=200)

  4 - filter(ROWNUM<=200)

  6 - access("T_S_TEL_RECORD"."EMPLOYEE_ID"=1067 AND "T_S_TEL_RECORD"."RESULT" IS NULL)

 

21 rows selected

 

=====================================================================

=====================================================================

rownum200就走组合索引,20就不走组合索引,我们看到取20的时候

INDEX FULL SCAN DESCENDING,这里就已经排序,oracle想通过全

索引扫描来避免order by(因为全索引扫描是排序的),而当取的数据

多了的时候,oracle认为排序和走组合索引效率更高。

 

实际上这里oracle判断出了问题, 因为不管是rownum这里取200还是20的时候

通过走组合索引的效率都要高于全索引扫描,在例子上我加如下hints

/*+ index(t_s_Tel_Record IDX_TEL_ZU)*/

效率仍然比走全索引扫描高,速度快了1

 

 

 

 

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10678398/viewspace-722127/,如需转载,请注明出处,否则将追究法律责任。

下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2010-11-30

  • 博文量
    36
  • 访问量
    56264