讨论ALL_ROWS模式和FIRST_ROWS模式

    在CBO的优化模式下,我们可以使用optimizer_mode参数控制优化模式。主要有两种模式,一种是ALL_ROWS模式,另外一种是FIRST_ROWS模式。

    ALL_ROWS模式适用场景:希望优化程序给出一种尽快得到全部记录的执行计划,目标是增加系统的吞吐量。

    FIRST_ROWS模式适用场景:希望优化程序给出一种可以迅速的得到第一行的执行计划,目标是减少系统的响应时间。

    两种模式需要具体场景具体分析,比如常见的Web应用,很少有一次性得到全部记录的情况,都是分多页交互的响应操作者,因此默认的ALL_ROWS模式就不太合适了,应该考虑使用FIRST_ROWS模式进行优化。又如,我们想要生成全部数据的报表,那么默认的ALL_ROWS模式就比较的合适。

    下面通过实验来比较all_rows和first_rows对执行计划的影响:

  1.实验环境:

  操作系统:rhel 5.4 x32

  数据库:oracle 11.2.0.1.0

  2.首先我们创建一个具有dba权限的用户jack_lin,default_tablespace使用默认的users。

1 SQL> conn /as sysdba
2 Connected.
3 SQL> create user jack_lin identified by jack;
4 User created.
5 SQL> grant dba to jack_lin;
6 Grant succeeded.

  3.创建该实验需要用到的一张表。

 1 SQL> conn jack_lin/jack;
 2 Connected.
 3 SQL> create table test(id number,name varchar2(10));
 4 Table created.
 5 SQL> insert into test values(100,'aaaa');
 6 1 row created.
 7 SQL> insert into test values(200,'bbbb');
 8 1 row created.
 9 SQL> insert into test values(300,'cccc');
10 1 row created.
11 SQL> insert into test values(400,'dddd');
12 1 row created.
13 SQL> commit;
14 Commit complete.

  4.在没有索引的情况比较:

  首先来看FIRST_ROWS的效果,为了保证CBO执行计划的准确,我们需要analyze一下表。

 1 SQL> alter session set optimizer_mode=first_rows;
 2 
 3 Session altered.
 4 
 5 SQL> analyze table test compute statistics;
 6 
 7 Table analyzed.
 8 
 9 SQL> set autotrace trace exp;
10 SQL> select * from test where name='aaaa';
11 
12 Execution Plan
13 ----------------------------------------------------------
14 Plan hash value: 1357081020
15 
16 --------------------------------------------------------------------------
17 | Id  | Operation      | Name | Rows  | Bytes | Cost (%CPU)| Time     |
18 --------------------------------------------------------------------------
19 |   0 | SELECT STATEMENT  |     |     1 |     6 |     3   (0)| 00:00:01 |
20 |*  1 |  TABLE ACCESS FULL| TEST |     1 |     6 |     3   (0)| 00:00:01 |
21 --------------------------------------------------------------------------
22 
23 Predicate Information (identified by operation id):
24 ---------------------------------------------------
25 
26    1 - filter("NAME"='aaaa')

  由于表上没有索引,所以只有一种选择,全表扫描。

  现在再看一下ALL_ROWS的情况:

 1 SQL> alter session set optimizer_mode=all_rows;
 2 
 3 Session altered.
 4 
 5 SQL> select * from test where name='aaaa';
 6 
 7 Execution Plan
 8 ----------------------------------------------------------
 9 Plan hash value: 1357081020
10 
11 --------------------------------------------------------------------------
12 | Id  | Operation      | Name | Rows  | Bytes | Cost (%CPU)| Time     |
13 --------------------------------------------------------------------------
14 |   0 | SELECT STATEMENT  |     |     1 |     6 |     3   (0)| 00:00:01 |
15 |*  1 |  TABLE ACCESS FULL| TEST |     1 |     6 |     3   (0)| 00:00:01 |
16 --------------------------------------------------------------------------
17 
18 Predicate Information (identified by operation id):
19 ---------------------------------------------------
20 
21    1 - filter("NAME"='aaaa')

  通过上面的简单举例比较,可以看到在表上没有索引,当数据量很少,并且值唯一的情况下,两种模式的效果是一样的。

  5.在有索引的情况下比较:

  创建索引,并执行在FIRST_ROWS的操作

 1 SQL> create index ind_test on test(name);
 2 
 3 Index created.
 4 
 5 SQL> analyze index ind_test compute statistics;
 6 
 7 Index analyzed.
 8 
 9 SQL> analyze table test compute statistics;
10 
11 Table analyzed.
12 
13 SQL>  select /*+ first_rows */* from test where name='aaaa';
14 
15 Execution Plan
16 ----------------------------------------------------------
17 Plan hash value: 3856466897
18 
19 ----------------------------------------------------------------------------------------
20 | Id  | Operation            | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
21 ----------------------------------------------------------------------------------------
22 |   0 | SELECT STATEMENT        |           |     1 |     6 |     2     (0)| 00:00:01 |
23 |   1 |  TABLE ACCESS BY INDEX ROWID| TEST     |     1 |     6 |     2     (0)| 00:00:01 |
24 |*  2 |   INDEX RANGE SCAN        | IND_TEST |     1 |       |     1     (0)| 00:00:01 |
25 ----------------------------------------------------------------------------------------
26 
27 Predicate Information (identified by operation id):
28 ---------------------------------------------------
29 
30    2 - access("NAME"='aaaa')

 

  设置成ALL_ROWS的情况:

 1 SQL> select /*+ all_rows */ * from test where name='aaaa';
 2 
 3 Execution Plan
 4 ----------------------------------------------------------
 5 Plan hash value: 3856466897
 6 
 7 ----------------------------------------------------------------------------------------
 8 | Id  | Operation            | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
 9 ----------------------------------------------------------------------------------------
10 |   0 | SELECT STATEMENT        |           |     1 |     6 |     2     (0)| 00:00:01 |
11 |   1 |  TABLE ACCESS BY INDEX ROWID| TEST     |     1 |     6 |     2     (0)| 00:00:01 |
12 |*  2 |   INDEX RANGE SCAN        | IND_TEST |     1 |       |     1     (0)| 00:00:01 |
13 ----------------------------------------------------------------------------------------
14 
15 Predicate Information (identified by operation id):
16 ---------------------------------------------------
17 
18    2 - access("NAME"='aaaa')

   通过上面的演示可以看到两种模式都走了索引,目前来看一切正常。

  6.现在通过insert into test select * from test;往test表中反复插入记录,注意记录大部分是重复的,其实只有四条,各占1/4。

 1 set autotrace off;
 2 SQL> insert into test select * from test;
 3 
 4 16384 rows created.
 5 SQL> analyze table test compute statistics;
 6 
 7 Table analyzed.
 8 SQL> analyze index ind_test compute statistics;
 9 
10 Index analyzed.
11 
12 SQL> alter session set optimizer_mode=first_rows;
13 
14 Session altered.
15 
16 SQL> set autotrace trace exp;
17 SQL> select * from test where name='aaaa';
18 
19 Execution Plan
20 ----------------------------------------------------------
21 Plan hash value: 3856466897
22 
23 ----------------------------------------------------------------------------------------
24 | Id  | Operation            | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
25 ----------------------------------------------------------------------------------------
26 |   0 | SELECT STATEMENT        |           |  8192 | 49152 |    87     (0)| 00:00:02 |
27 |   1 |  TABLE ACCESS BY INDEX ROWID| TEST     |  8192 | 49152 |    87     (0)| 00:00:02 |
28 |*  2 |   INDEX RANGE SCAN        | IND_TEST |  8192 |       |    28     (0)| 00:00:01 |
29 ----------------------------------------------------------------------------------------
30 
31 Predicate Information (identified by operation id):
32 ---------------------------------------------------
33 
34    2 - access("NAME"='aaaa')
35 
36 SQL> alter session set optimizer_mode=all_rows;
37 
38 Session altered.
39 
40 SQL> select * from test where name='aaaa';
41 
42 Execution Plan
43 ----------------------------------------------------------
44 Plan hash value: 1357081020
45 
46 --------------------------------------------------------------------------
47 | Id  | Operation      | Name | Rows  | Bytes | Cost (%CPU)| Time     |
48 --------------------------------------------------------------------------
49 |   0 | SELECT STATEMENT  |     |  8192 | 49152 |    19   (0)| 00:00:01 |
50 |*  1 |  TABLE ACCESS FULL| TEST |  8192 | 49152 |    19   (0)| 00:00:01 |
51 --------------------------------------------------------------------------
52 
53 Predicate Information (identified by operation id):
54 ---------------------------------------------------
55 
56    1 - filter("NAME"='aaaa')

  这时我们看到FIRST_ROWS走了索引,就本例而言,这显然不是一种理想的结果,而ALL_ROWS走了全表扫描,我们可以看到成本明显更低。

  参考一下Oracle 10g官方文档关于optimizer_mode参数的描述

OPTIMIZER_MODE

PropertyDescription
Parameter typeString
SyntaxOPTIMIZER_MODE =

{ first_rows_[1 | 10 | 100 | 1000] | first_rows | all_rows }

Default valueall_rows
ModifiableALTER SESSION, ALTER SYSTEM

OPTIMIZER_MODE establishes the default behavior for choosing an optimization approach for the instance.

Values:

  • first_rows_n

    The optimizer uses a cost-based approach and optimizes with a goal of best response time to return the first n rows (where n = 1, 10, 100, 1000).

  • first_rows

    The optimizer uses a mix of costs and heuristics to find a best plan for fast delivery of the first few rows.

  • all_rows

    The optimizer uses a cost-based approach for all SQL statements in the session and optimizes with a goal of best throughput (minimum resource use to complete the entire statement).

  总结:

  Oracle默认的优化模式并不一定是我们想要的,必须根据自己的系统特定细心的定制。

 

 

 

转载于:https://www.cnblogs.com/Richardzhu/articles/2814599.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/424197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第一百零三期:解读回归测试:类型、选择、挑战和实践

本文介绍了回归测试的基本概念、工作方式、面临的挑战、以及业界的优秀实践。 作者:陈峻编译 【51CTO.com快译】有研究表明:在安装了新的应用程序之后,只有四分之一的用户会在次日回到该应用。而大多数用户在首次使用之后就直接将其卸载掉了…

126. Word Ladder II

文章目录1 题目理解2 BFS1 题目理解 题目要求和127是一样的。返回值不一样。返回值要求把最短路径的,具体路径输出。 Input: beginWord “hit”, endWord “cog”, wordList [“hot”,“dot”,“dog”,“lot”,“log”,“cog”] Output: [ [“hit”,“hot”,“…

如何构建积木式Web应用

上下文基本上我们在儿童时代都玩过积木玩具。通过一块块的积木,再加上我们的想象力,就可以构造出非常多不同的风格的建筑。那么, 我们可不可以把这种搭积木的方式应用到我们的web应用上呢。问题web应用通过提供给用户一整套组件(相…

第一百零四期:搞清这些陷阱,NULL和三值逻辑再也不作妖

NULL 用于表示缺失的值或遗漏的未知数据,不是某种具体类型的值。数据表中的 NULL 值表示该值所处的字段为空,值为 NULL 的字段没有值,尤其要明白的是:NULL 值与 0 或者空字符串是不同的。 作者:youzhibing2904 NULL …

752. Open the Lock

文章目录1 题目理解2 BFS3 用int构建状态1 题目理解 一个钟表有4个槽,每个槽可以停在0-9,10个状态。钟表每个槽的轮子可以转,例如可以从0转到9,也可以从0转到1。 钟表的起始状态是"0000"。每个数字代表一个槽的状态。 …

移动开发 视频收集

构建基于SQL CE的移动方案http://download.chinaitlab.com/video/files/8282.html转载于:https://www.cnblogs.com/Regal/archive/2006/03/23/356800.html

移动混合开发之android文件管理新建文件和删除文件

今天经过一天超过8小时的实践,有很多CSS上的细节需要注意: 1, /*注意是对before的操作*/ .content ul li .icon-check-empty:before{display: block;/*webFont设置其width和height时无效,只有设置font-size*//*width: 3rem;*//*height: 3rem;…

spring mvc学习(19):cookievalue注解(显示cookie的值,默认必须有值)

目录结构 web.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns"http://java.sun.com/xml/ns/javaee" xsi:schemaLocation"http://java.sun.com/xml…

续:C#串口操作

今天继续写C#的工业扫描串口。突然遇到一个很奇怪的问题&#xff1a;那就是我要求把某些码得到之后进行业务处理&#xff0c;但是就是这个时候突然发现扫描出来的 码位数不正确了&#xff01;我就很怀疑自己的代码逻辑了。于是&#xff0c;我就逐行进行调试&#xff0c;而接受口…

spring mvc学习(20):RequestHeader(获取请求头中某一部分值)

目录结构 web.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns"http://java.sun.com/xml/ns/javaee" xsi:schemaLocation"http://java.sun.com/xml…

698. Partition to K Equal Sum Subsets

文章目录1 理解题目2 分析2.1进一步优化2.2 根据花花酱解答1 理解题目 Given an array of integers nums and a positive integer k, find whether it’s possible to divide this array into k non-empty subsets whose sums are all equal. 输入&#xff1a;一个int数组nums…

spring mvc学习(21):testparam请求参数和请求头表达式

目录结构 web.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns"http://java.sun.com/xml/ns/javaee" xsi:schemaLocation"http://java.sun.com/xml…

OpenGL ES GLKit初探

#GLKit框架 GLKit框架的设计目的是为了简化OpenGL/OpenGL ES的应用开发。它的出现加快了OpenGL或OpenGL ES应用程序的开发。使用数学库、背景纹理加载&#xff0c;预先创建着色器效果&#xff0c;以及标准视图和视图控制器来实现渲染循环。 GLKit框架提供了功能和类&#xff0c…

一个封装了的ADO类,功能非常强大,并做了一个DEMO演示如何操作ACCESS数据库

呵呵&#xff0c;说实在的&#xff0c;这个类俺是从外国论坛上下载的&#xff0c;自己研究了下如何使用并做了一个DEMO&#xff0c;演示如何操作ACCESS数据库。希望给那些没有接触数据库编程的初学者一点启发吧。有任何问题请及时与我联系^_^。程序下载地址&#xff1a;/Files/…

93. Restore IP Addresses

文章目录1 题目理解2 回溯1 题目理解 输入&#xff1a;字符串s 输出&#xff1a;可能的ip地址 规则&#xff1a;一个有效的ip地市是一连串数字&#xff0c;数字范围在0到255&#xff0c;每个数字不能有前导0。例如"0.1.2.201" and "192.168.1.1"是有效ip地…

spring mvc学习(22):/textpath/*/helen

目录结构 web.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns"http://java.sun.com/xml/ns/javaee" xsi:schemaLocation"http://java.sun.com/xml…

131. Palindrome Partitioning

文章目录1 题目理解2 回溯3 动态规划1 题目理解 输入&#xff1a;字符串s 规则&#xff1a;将字符串s分割&#xff0c;分割后每一个部分都是一个回文串。 输出&#xff1a;所有的分割方式 Example 1: Input: s “aab” Output: [[“a”,“a”,“b”],[“aa”,“b”]] Examp…

4 文件操作 支持图片 视频 mp3 文本等

#文件操作:send_file,支持图片 视频 mp3 文本等app.route("/img")def img(): return send_file("1.jpg")转载于:https://www.cnblogs.com/ajaxa/p/11156483.html

我的博客开张了!!!

留个脚印,嘻嘻! 转载于:https://www.cnblogs.com/stu-acer/archive/2006/04/26/385453.html

第一百零五期:5年前,跳槽涨薪,你笑了,5年后,跳槽降薪,你慌了!

去年&#xff0c;我在年度绩效面谈中与某中年技术男就 “从测试转向产品经理” 的这个话题上进行了一些探讨与分析。 作者&#xff1a;王晔倞 图片来自 Pexels 或许是因为分析的角度比较客观、真实&#xff0c;再加上俩人都比较会演戏&#xff0c;我激情&#xff0c;他投入&a…