ITPub博客

首页 > 应用开发 > IT综合 > 【转载】 yangtingkun: 利用执行计划来避免排序操作(一)

【转载】 yangtingkun: 利用执行计划来避免排序操作(一)

原创 IT综合 作者:xiaopingzhang 时间:2011-01-12 17:11:35 0 删除 编辑

很多执行计划本身就是需要排序的,通过特定的执行计划可以避免排序的产生。前两天在论坛中看到类似的问题。这里简单总结一下。

利用执行计划来避免排序操作(二):http://yangtingkun.itpub.net/post/468/243463

索引全扫描可以避免排序,相信大部分人都很清楚:

SQL> CREATE TABLE T_NOSORT (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30) NOT NULL);

表已创建。

SQL> CREATE INDEX IND_T_NOSORT_NAME ON T_NOSORT(NAME);

索引已创建。

SQL> INSERT INTO T_NOSORT SELECT ROWNUM, TABLE_NAME FROM USER_TABLES;

已创建15行。

SQL> COMMIT;

提交完成。

SQL> SET AUTOT ON EXP
SQL> SELECT ID, NAME FROM T_NOSORT ORDER BY NAME;

ID NAME
---------- ------------------------------
5 BONUS
2 CHAINED_ROWS
3 DEPT 1 DR$IND_T_DOCS$I
15 DR$IND_T_DOCS$K
14 DR$IND_T_DOCS$N
9 DR$IND_T_DOCS$R
7 DUMMY
4 EMP
6 SALGRADE
8 T
12 T_DUMP
13 T_IOT
10 T_NOSORT
11 T_OTHER

已选择15行。

执行计划
----------------------------------------------------------
Plan hash value: 1041838668

-------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
-------------------------------------------------------
| 0 | SELECT STATEMENT | | 15 | 450 |
| 1 | SORT ORDER BY | | 15 | 450 |
| 2 | TABLE ACCESS FULL| T_NOSORT | 15 | 450 |
-------------------------------------------------------

SQL> SELECT /*+ INDEX(T_NOSORT IND_T_NOSORT_NAME) */ ID, NAME FROM T_NOSORT ORDER BY NAME;

ID NAME
---------- ------------------------------
5 BONUS
2 CHAINED_ROWS
3 DEPT 1 DR$IND_T_DOCS$I
15 DR$IND_T_DOCS$K
14 DR$IND_T_DOCS$N
9 DR$IND_T_DOCS$R
7 DUMMY
4 EMP
6 SALGRADE
8 T
12 T_DUMP
13 T_IOT
10 T_NOSORT
11 T_OTHER

已选择15行。

执行计划
----------------------------------------------------------
Plan hash value: 3156728236

------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 15 | 450 |
| 1 | TABLE ACCESS BY INDEX ROWID| T_NOSORT | 15 | 450 |
| 2 | INDEX FULL SCAN | IND_T_NOSORT_NAME| 15 | |
------------------------------------------------------------------------

同样的道理,索引范围扫描也是可以避免排序的:

SQL> SELECT ID, NAME FROM T_NOSORT WHERE NAME < 'I' ORDER BY NAME;

ID NAME
---------- ------------------------------
5 BONUS
2 CHAINED_ROWS
3 DEPT 1 DR$IND_T_DOCS$I
15 DR$IND_T_DOCS$K
14 DR$IND_T_DOCS$N
9 DR$IND_T_DOCS$R
7 DUMMY
4 EMP

已选择9行。

执行计划
----------------------------------------------------------
Plan hash value: 1041838668

-------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
-------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 270 |
| 1 | SORT ORDER BY | | 9 | 270 |
|* 2 | TABLE ACCESS FULL| T_NOSORT | 9 | 270 |
-------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - filter("NAME"<'I')

SQL> SELECT /*+ INDEX(T_NOSORT IND_T_NOSORT_NAME) */ ID, NAME
2 FROM T_NOSORT WHERE NAME < 'I' ORDER BY NAME;

ID NAME
---------- ------------------------------
5 BONUS
2 CHAINED_ROWS
3 DEPT 1 DR$IND_T_DOCS$I
15 DR$IND_T_DOCS$K
14 DR$IND_T_DOCS$N
9 DR$IND_T_DOCS$R
7 DUMMY
4 EMP

已选择9行。

执行计划
----------------------------------------------------------
Plan hash value: 919790285

-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9 | 270 |
| 1 | TABLE ACCESS BY INDEX ROWID| T_NOSORT | 9 | 270 |
|* 2 | INDEX RANGE SCAN | IND_T_NOSORT_NAME | 9 | |
-------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("NAME"<'I')
filter("NAME"<'I')

对于上面的排序,如果是倒序排列,那么可以选择INDEX_DESC扫描来避免排序:

SQL> SELECT /*+ INDEX_DESC(T_NOSORT IND_T_NOSORT_NAME) */ ID, NAME
2 FROM T_NOSORT ORDER BY NAME DESC;

ID NAME
---------- ------------------------------
11 T_OTHER
10 T_NOSORT
13 T_IOT
12 T_DUMP
8 T
6 SALGRADE
4 EMP
7 DUMMY
9 DR$IND_T_DOCS$R
14 DR$IND_T_DOCS$N
15 DR$IND_T_DOCS$K
1 DR$IND_T_DOCS$I
3
DEPT 2 CHAINED_ROWS
5 BONUS

已选择15行。

执行计划
----------------------------------------------------------
Plan hash value: 2858378269

-------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
-------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 15 | 450 |
| 1 | TABLE ACCESS BY INDEX ROWID| T_NOSORT | 15 | 450 |
| 2 | INDEX FULL SCAN DESCENDING| IND_T_NOSORT_NAME | 15 | |
-------------------------------------------------------------------------

同样的原理还应用于索引组织表之中,按照索引组织表的主键排序和上面描述的索引排序没有什么区别。

这里需要强调一点,这里只是列举能够避免排序的执行计划,并非意味着避免了排序就一定会带来性能的提升,如果为了避免排序而选择了不恰当的执行计划,那么代价可能会比执行排序操作的代价要大得多。

[@more@]

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

请登录后发表评论 登录
全部评论
  • 博文量
    24
  • 访问量
    25916