在oracle中,利用index来避免排序

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;
SQL> COMMIT;
SQL> SET AUTOT ON EXP
SQL> SELECT ID, NAME FROM T_NOSORT ORDER BY NAME;
----------------------------------------------------------
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 |
-------------------------------------------------------
QL> SELECT /*+ INDEX(T_NOSORT IND_T_NOSORT_NAME) */ ID, NAME FROM T_NOSORT ORDER BY NAME;
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 41 | 1230 | 827 (1)| 00:00:10 |
| 1 | TABLE ACCESS BY INDEX ROWID| T_NOSORT | 41 | 1230 | 827 (1)| 00:00:10 |
| 2 | INDEX FULL SCAN | IND_T_NOSORT_NAME | 41 | | 26 (0)| 00:00:01 |

利用索引范围扫描

SQL> SELECT ID, NAME FROM T_NOSORT WHERE NAME < 'I' ORDER BY NAME;
----------------------------------------------------------
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;
----------------------------------------------------------
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')

如果是倒序排序

QL> SELECT /*+ INDEX_DESC(T_NOSORT IND_T_NOSORT_NAME) */ ID, NAME 
2 FROM T_NOSORT ORDER BY NAME DESC;
----------------------------------------------------------
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 | |
-------------------------------------------------------------------------

这里只是说明了能够避免排序的执行计划,但是不一定能提升性能

上面针对于单表

MERGE JOIN连接方式

SQL> CREATE TABLE T1 (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30) NOT NULL);
SQL> CREATE TABLE T2 (ID NUMBER, NAME VARCHAR2(30));
SQL> CREATE INDEX IND_T1_NAME ON T1(NAME);
SQL> INSERT INTO T1 SELECT ROWNUM, TABLE_NAME FROM USER_TABLES;
SQL> INSERT INTO T2 SELECT ROWNUM, OBJECT_NAME FROM USER_OBJECTS;
SQL> COMMIT;
SQL> SET AUTOT ON EXP
SQL> SELECT /*+ USE_MERGE(T1, T2) */ T2.NAME, T1.ID FROM T1, T2
WHERE T1.NAME = T2.NAME ;
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 41 | 1927 | 8 (25)| 00:00:01 |
| 1 | MERGE JOIN | | 41 | 1927 | 8 (25)| 00:00:01 |
| 2 | SORT JOIN | | 41 | 1230 | 4 (25)| 00:00:01 |
| 3 | TABLE ACCESS FULL| T1 | 41 | 1230 | 3 (0)| 00:00:01 |
|* 4 | SORT JOIN | | 99 | 1683 | 4 (25)| 00:00:01 |
| 5 | TABLE ACCESS FULL| T2 | 99 | 1683 | 3 (0)| 00:00:01 |
----------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("T1"."NAME"="T2"."NAME")
filter("T1"."NAME"="T2"."NAME")
SQL> SELECT /*+ USE_MERGE(T2, T1) */ T2.NAME, T1.ID
FROM T1, T2 WHERE T1.NAME = T2.NAME ORDER BY T2.NAME ;
----------------------------------------------------
Plan hash value: 412793182
----------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
----------------------------------------------------
| 0 | SELECT STATEMENT | | 19 | 893 |
| 1 | MERGE JOIN | | 19 | 893 |
| 2 | SORT JOIN | | 17 | 510 |
| 3 | TABLE ACCESS FULL| T1 | 17 | 510 |
|* 4 | SORT JOIN | | 97 | 1649 |
| 5 | TABLE ACCESS FULL| T2 | 97 | 1649 |
----------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("T1"."NAME"="T2"."NAME")
filter("T1"."NAME"="T2"."NAME")

针对merge join只能对连接的列排序,且排序操作只能是升序

SQL> SELECT /*+ USE_MERGE(T2, T1) */ T2.NAME, T1.ID
FROM T1, T2 WHERE T1.NAME = T2.NAME ORDER BY T2.NAME DESC;
| 0 | SELECT STATEMENT | | 41 | 1927 | 9 (34)| 00:00:01 |
| 1 | SORT ORDER BY | | 41 | 1927 | 9 (34)| 00:00:01 |
| 2 | MERGE JOIN | | 41 | 1927 | 8 (25)| 00:00:01 |
| 3 | SORT JOIN | | 41 | 1230 | 4 (25)| 00:00:01 |
| 4 | TABLE ACCESS FULL| T1 | 41 | 1230 | 3 (0)| 00:00:01 |
|* 5 | SORT JOIN | | 99 | 1683 | 4 (25)| 00:00:01 |
| 6 | TABLE ACCESS FULL| T2 | 99 | 1683 | 3 (0)| 00:00:01 |5 - access("T1"."NAME"="T2"."NAME")
filter("T1"."NAME"="T2"."NAME")

NESTED LOOP连接

由于nested loop不会对操作结果排序,所以结果是无序的

如果驱动表在连接前是有序的,在连接后,结果还是有序的

SQL> CREATE INDEX IND_T2_ID ON T2(ID);
SQL> CREATE INDEX IND_T2_NAME ON T2(NAME);
SQL> SELECT /*+ USE_NL(T1, T2) */ T1.ID, T1.NAME, T2.NAME 
2 FROM T1, T2
3 WHERE T1.ID = T2.ID
4 ;
----------------------------------------------------------
Plan hash value: 3621112097
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 17 | 1020 | 
| 1 | TABLE ACCESS BY INDEX ROWID| T2 | 1 | 30 | 
| 2 | NESTED LOOPS | | 17 | 1020 | 
| 3 | TABLE ACCESS FULL | T1 | 17 | 510 | 
|* 4 | INDEX RANGE SCAN | IND_T2_ID | 1 | | 
----------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - access("T1"."ID"="T2"."ID")
SQL> SELECT /*+ ORDERED INDEX(T1 IND_T1_NAME) USE_NL(T1, T2) */ 
2 T1.ID, T1.NAME, T2.NAME 
3 FROM T1, T2
4 WHERE T1.ID = T2.ID
5 ORDER BY T1.NAME
6 ; ----------------------------------------------------------
Plan hash value: 1062594094
---------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
---------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 17 | 1020 |
| 1 | TABLE ACCESS BY INDEX ROWID | T2 | 1 | 30 |
| 2 | NESTED LOOPS | | 17 | 1020 |
| 3 | TABLE ACCESS BY INDEX ROWID| T1 | 17 | 510 |
| 4 | INDEX FULL SCAN | IND_T1_NAME | 17 | |
|* 5 | INDEX RANGE SCAN | IND_T2_ID | 1 | |
---------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("T1"."ID"="T2"."ID")
SQL> ALTER TABLE T2 MODIFY NAME NOT NULL;
SQL> CREATE INDEX IND_T2_NAME ON T2(NAME);
SQL> SET AUTOT OFF
SQL> UPDATE T2 SET ID = MOD(ID, 17) + 1;
SQL> COMMIT;
SQL> SET AUTOT ON EXP
SQL> SELECT /*+ ORDERED INDEX(T1 IND_T1_NAME) 
2 INDEX(T2 IND_T2_NAME) USE_NL(T1, T2) */ 
3 T1.ID, T1.NAME, T2.NAME 
4 FROM T1, T2
5 WHERE T1.ID = T2.ID
6 ORDER BY T1.NAME
7 ;
----------------------------------------------------------
Plan hash value: 3719138605
---------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
---------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 97 | 5820 |
|* 1 | TABLE ACCESS BY INDEX ROWID | T2 | 6 | 180 |
| 2 | NESTED LOOPS | | 97 | 5820 |
| 3 | TABLE ACCESS BY INDEX ROWID| T1 | 17 | 510 |
| 4 | INDEX FULL SCAN | IND_T1_NAME | 17 | |
| 5 | INDEX FULL SCAN | IND_T2_NAME | 97 | |
---------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("T1"."ID"="T2"."ID") SQL> SELECT /*+ ORDERED INDEX(T1 IND_T1_NAME) 
2 INDEX_DESC(T2 IND_T2_NAME) USE_NL(T1, T2) */ 
3 T1.ID, T1.NAME, T2.NAME 
4 FROM T1, T2
5 WHERE T1.ID = T2.ID
6 ORDER BY T1.NAME
7 ;
----------------------------------------------------------
Plan hash value: 2531946081
---------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
---------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 97 | 5820 |
|* 1 | TABLE ACCESS BY INDEX ROWID | T2 | 6 | 180 |
| 2 | NESTED LOOPS | | 97 | 5820 |
| 3 | TABLE ACCESS BY INDEX ROWID| T1 | 17 | 510 |
| 4 | INDEX FULL SCAN | IND_T1_NAME | 17 | |
| 5 | INDEX FULL SCAN DESCENDING | IND_T2_NAME | 97 | |
---------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("T1"."ID"="T2"."ID")
SQL> SELECT /*+ ORDERED INDEX(T1 IND_T1_NAME) 
2 INDEX(T2 IND_T2_NAME) USE_NL(T1, T2) */ 
3 T1.ID, T1.NAME, T2.NAME 
4 FROM T1, T2
5 WHERE T1.ID = T2.ID
6 ORDER BY T1.NAME, T2.NAME DESC
7 ; ----------------------------------------------------------
Plan hash value: 1438746903
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |
----------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 97 | 5820 |
| 1 | SORT ORDER BY | | 97 | 5820 |
|* 2 | TABLE ACCESS BY INDEX ROWID | T2 | 6 | 180 |
| 3 | NESTED LOOPS | | 97 | 5820 |
| 4 | TABLE ACCESS BY INDEX ROWID| T1 | 17 | 510 |
| 5 | INDEX FULL SCAN | IND_T1_NAME | 17 | |
| 6 | INDEX FULL SCAN | IND_T2_NAME | 97 | |
----------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("T1"."ID"="T2"."ID")

Oracle 利用执行计划来避免排序操作的更多相关文章

  1. Oracle sql执行计划解析

    Oracle sql执行计划解析 https://blog.csdn.net/xybelieve1990/article/details/50562963 Oracle优化器 Oracle的优化器共有 ...

  2. 怎样看懂Oracle的执行计划

    怎样看懂Oracle的执行计划 一.什么是执行计划 An explain plan is a representation of the access path that is taken when ...

  3. (转)Oracle定时执行计划任务

    Oracle定时执行计划任务 在日常工作中,往往有些事情是需要经常重复地做的,例如每天更新业务报表.每天从数据库中提取符合条件的数据.每天将客户关系管理系统中的数据分配给员工做数据库营销……因此我们就 ...

  4. 【ORACLE】记录通过执行Oracle的执行计划查询SQL脚本中的效率问题

    记录通过执行Oracle的执行计划查询SQL脚本中的效率问题   问题现象: STARiBOSS5.8.1R2版本中,河北对帐JOB执行时,无法生成发票对帐文件.   首先,Quartz表达式培植的启 ...

  5. Oracle的执行计划(来自百度文库)

    如何开启oracle执行计划 http://wenku.baidu.com/view/7d1ff6bc960590c69ec37636.html怎样看懂Oracle的执行计划 http://wenku ...

  6. ORACLE的执行计划

    转自:http://www.cnblogs.com/lovingprince/archive/2007/12/07/2166400.html 背景知识:        为了更好的进行下面的内容我们必须 ...

  7. oracle 理解执行计划

    ·BUFFER SORT是BUFFER却不是SORT 用AUTOTRACE查看执行的计划的同学常问到执行计划里的BUFFER SORT是什么意思,这里为什么要排序呢? BUFFER SORT不是一种排 ...

  8. 分析oracle的执行计划(explain plan)并对对sql进行优化实践

    基于oracle的应用系统很多性能问题,是由应用系统sql性能低劣引起的,所以,sql的性能优化很重要,分析与优化sql的性能我们一般通过查看该sql的执行计划,本文就如何看懂执行计划,以及如何通过分 ...

  9. oracle sql 执行计划分析

    转自http://itindex.net/detail/45962-oracle-sql-%E8%AE%A1%E5%88%92 一.首先创建表 SQL> show user USER is &q ...

随机推荐

  1. tensorflow笔记:使用tf来实现word2vec

    (一) tensorflow笔记:流程,概念和简单代码注释 (二) tensorflow笔记:多层CNN代码分析 (三) tensorflow笔记:多层LSTM代码分析 (四) tensorflow笔 ...

  2. 今夜我们一起学习 Apache Shiro

    简介 Apache Shiro 是一个功能强大但又非常容易使用的 Java 安全框架,提供了认证,授权,加密以及会话管理功能.因为 Shiro 的 API 是非常容易理解的,所以使用 Shiro 你可 ...

  3. 包嗅探和包回放 —tcpdump、tcpreplay--重放攻击

    攻击方式:tcpdump 进行嗅探,获取报文消息:然后用tcpreplay回放攻击 arp欺骗可以使用 arpspoof kali linux有这三个工具 转载地址https://www.cnblog ...

  4. go语言的一个简单httpserver

    httpserver.go package main import ( "net/http" "flag" "fmt" "log& ...

  5. 四十九 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索结果分页

    逻辑处理函数 计算搜索耗时 在开始搜索前:start_time = datetime.now()获取当前时间 在搜索结束后:end_time = datetime.now()获取当前时间 last_t ...

  6. AI实现五子棋机器人(一)

    前言: 前几天在 csdn 下载资源的时候才发现自己 csdn 有近 200 的下载积分,看了看共享的资源,哈哈 ... 7年前写的五子棋游戏很受欢迎. 下载地址:新手入门五子棋游戏     刚入行的 ...

  7. SpringCloud教程 | 第十一篇: docker部署spring cloud项目

    版权声明:本文为博主原创文章,欢迎转载,转载请注明作者.原文超链接 ,博主地址:http://blog.csdn.net/forezp. http://blog.csdn.net/forezp/art ...

  8. 接口取不到POST参数

    利用类似httprequester小工具调试API时偶尔出现一直取不到POST的数据 解决方式: 1.$_POST['paramName']: 只能接收Content-Type: applicatio ...

  9. PhotoPicker 从头到脚

    1. 简介 PhotoPicker, 是一款开源的图片选择器.效果上和微信相似. 2. 使用方法 2.1 添加依赖 dependencies { compile 'me.iwf.photopicker ...

  10. jQuery attr 与 prop 区别最简单分析

    比较经典的解释: 在处理html元素本身就带有的固有属性时,使用prop方法,对于html元素中,我们自己定义的dom属性时,使用attr方法. 而咱自己的理解是: attr会忠实的获取设置dom标签 ...