ORACLE优化器

一ORACLE优化器概述ORACLE优化器是用于生成SQL语句访问数据库时使用的执行计划的。ORACLE优化器通过使用ORACLE搜集的关于数据库对象的统计数据来生成SQL语句的访问计划(使用什么对象)并执行计划(使用何种操作)    二ORACLE优化器的分类 ORACLE优化器分为三类:1)RULE优化器:基于规则的优化器相对比较简单,通过检查数据库的

大家好,又见面了,我是你们的朋友全栈君。

ORACLE优化器概述

ORACLE优化器是用于生成SQL语句访问数据库时使用的执行计划的。ORACLE优化器通过使用ORACLE搜集的关于数据库对象的统计数据来生成SQL语句的访问计划(使用什么对象)并执行计划(使用何种操作)

 

 

 

 

ORACLE优化器的分类

 

ORACLE优化器分为三类:

1) RULE优化器:基于规则的优化器相对比较简单,通过检查数据库的可用路径并将这些路径与路径表进行比较,从而确定SQL语句的执行计划。RULE优化的过程中不需要任何表或索引的统计信息,而且也会忽略任何表或索引的统计信息

2) COST优化器:基于开销的优化器相对比较复杂,通过使用数据库的结构和数据等信息来选择最优的执行计划。优化的过程中需要相关表和索引的统计信息。

3) CHOOSE优化器:在存在相关统计信息的情况下采用基于开销的优化器,在不存在相关统计信息的情况下才用基于规则的优化器。这是8I中默认的优化器工作方式

 

查询当前优化器的工作方式

查询当前优化器的工作方式比较简单的方法有以下两种:

1) 查看ORACLE数据库的初始化文件,看看初始化参数optimizer_mode的取值

2) SQL> select name,value from v$parameter where name = ‘optimizer_mode’;

NAME VALUE

————— ———————————————————

optimizer_mode CHOOSE

 

修改优化器的工作模式

可以使用下面的两种方法来选择优化器模式(基于开销的模式和基于规则的模式):

1) 初始化参数optimizer_mode

2) alter session 命令的 optimizer_goal参数

选择优化器模式时所能使用的选项

l choose:这个选项允许优化器根据特定表或索引的统计数据的可用性选择优化模式。如果sql语句中涉及到的表中有一个表有统计数据,那么优化器将选择基于开销的优化方法;否则如果所有表都没有统计数据,那么优化器将选择基于规则的优化模式

l rule:这个选项将导致优化器总是使用基于规则的优化方法,而不管系统中是否存在被访问表的统计数据

l all_rows:这个选项将导致优化器对所有的sql语句都使用基于开销的优化方法,即使对于系统中不存在可用统计数据的表,情况也是如此。这个选项的目的是使用最少的系统资源获得最大的吞吐量,力求完成sql语句的总花费为最少

l first_rows_n:这个选项将导致优化器对所有的sql语句都使用基于开销的优化方法,即使对于系统中不存在可用统计数据的表,情况也是如此。这个选项的目的是获得最快的响应时间,力求最快返回结果中的前n条记录

 

基于规则的优化器

因为我们现在的测试环境和所有的医保中心以及定点医疗机构都是采用默认的choose优化器选项,而且所有的表和索引等也没有相关的统计信息,所以实际上oracle数据库都是运行在rule的优化器模式下。下面详细的介绍一下基于规则的优化器模式,对基于开销的优化器仅做简单的介绍。

在基于规则的和基于开销的优化器中,基于规则的优化器相对来说比较简单。在基于规则的优化方法中,优化器通过检查数据库的可用路径并将这些路径与路径表进行比较,从而确定sql语句的执行计划。下面的表中包含了与各种不同访问路径相关的开销

级别

访问路径

1

通过rowid访问单行数据

2

通过簇连接访问单行数据

3

通过带惟一键或主键的散列簇访问单行数据

4

通过惟一键或主键访问单行数据

5

簇连接

6

散列簇键

7

索引簇键

8

复合键

9

单字段索引

10

在索引字段上有边界的范围内搜索数据

11

在索引字段上无边界的范围内搜索数据

12

排序合并连接

13

搜索索引字段的最大或最小值

14

对索引字段使用order by操作

15

全表扫描

举个最简单的例子来说明基于规则的优化器如果选择执行路径

建立测试用表

SQL> drop table test;

表已丢弃。

SQL> create table test

2 (id varchar2(3),

3 name varchar2(10))

4 tablespace test;

表已创建。

SQL> insert into test values (‘001′,’tom’);

已创建 1 行。

SQL> commit;

提交完成。

没有建立的索引的情况下,该sql执行的唯一方式就是全表扫描(即使全表扫描被规则优化器认为是最慢的一种方式)

SQL> set autotrace on

SQL> select * from test where id=’001′;

ID NAME

— ———-

001 tom

Execution Plan

———————————————————-

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 TABLE ACCESS (FULL) OF ‘TEST’

testid字段上建立索引后,上面这条sql语句就存在两种执行方案,一是全表扫描(15),另一种就是单字段索引(9)。Oracle根据前面的规则认为后者的开销比较小,所以优化器选择通过索引的扫描。

SQL> create index idx_test on test(id);

索引已创建。

SQL> select * from test where id=’001′;

ID NAME

— ———-

001 tom

Execution Plan

———————————————————-

0 SELECT STATEMENT Optimizer=CHOOSE

1 0 TABLE ACCESS (BY INDEX ROWID) OF ‘TEST’

2 1 INDEX (RANGE SCAN) OF ‘IDX_TEST’ (NON-UNIQUE)

上面的这个例子说明了基于规则的优化器的工作方式。基于规则的优化器原理比较简单,可以给系统提供比较好的执行计划的稳定性。

 

基于开销的优化器

基于开销的优化器需要表或索引上的统计信息,他根据这些统计信息来为sql选择一条他认为是开销最小的执行路径。由于数据库里面的数据是一直在变化的,所以统计信息也应该及时的更新,这样才可以为基于开销提供准确的信息,为sql提供更加优化的方案。

SQL> alter session set OPTIMIZER_MODE=all_rows;

会话已更改。

SQL> analyze table test compute statistics;

表已分析。

SQL> select * from test where id=’001′;

ID NAME

— ———-

001 tom

Execution Plan

———————————————————-

0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=1 Card=1 Bytes=6)

1 0 TABLE ACCESS (FULL) OF ‘TEST’ (Cost=1 Card=1 Bytes=6)

虽然test表上存在索引,但是由于表中仅有一条记录,所以全表扫描的开销应该比通过索引来查找记录要小的多。因此基于开销的优化器选择了全表扫描。从上面的两个例子的对比来看只要有了统计信息,基于开销的优化器比基于规则的优化器要聪明的多。

 

总结

一般来说8i以下的数据库使用基于规则的优化器比较合适,因为这些版本里面的基于开销的优化器并不完善,为sql语句提供的执行路径并不总是最优的;而8i以及以上的版本,基于开销的优化器已经比较完善了,可以很好的代替基于规则的优化器来工作了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/126366.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 设计模式之工厂模式建议收藏

    一普通工厂模式1.类图2.代码实现#pragmaonce#include<iostream>usingnamespacestd;//抽象渲染类classIR

    2021年12月19日
    47
  • MATLAB02:结构化编程和函数定义「建议收藏」

    文章目录MATLAB02:结构化编程和函数定义结构化编程流程控制语句和逻辑运算符流程控制语句示例使用循环语句应尽量预先分配内存空间MATLAB02:结构化编程和函数定义结构化编程流程控制语句和逻辑运算符与大多数编程语言相同,MATLAB有以下流程控制语句:流程控制语句作用if,elseif,else若if语句为真,则执行子句switch,case,ot…

    2022年4月13日
    42
  • printwriter用法_class类反射方法

    printwriter用法_class类反射方法1.java.io.PrintWriter是java中很常见的一个类,该类可用来创建一个文件并向文本文件写入数据。可以理解为java中的文件输出,java中的文件输入则是java.io.File。2.常用的构造方法:注:java.io.PrintWriter的构造方法并不局限于一下范例,java.io.PrintWriter构造方法的参数也可以是字节流。因为本篇文章主要讲关于文件的操作,所以参数是…

    2022年8月10日
    8
  • 常用的数据库函数_数据库中自定义函数

    常用的数据库函数_数据库中自定义函数1.COALESCE();很多人知道ISNULL函数,但是很少人知道Coalesce函数,人们会无意中使用到Coalesce函数,并且发现它比ISNULL更加强大,其实到目前为止,这个函数的确非常有用。返回其参数中第一个非空表达式语法:COALESCE(expression[,…n])如果所有参数均为NULL,则COALESCE返回NULL。至少应有一个Null…

    2025年7月25日
    4
  • pycharm安装torch和cuda(在anaconda创建的新环境下)[通俗易懂]

    pycharm安装torch和cuda(在anaconda创建的新环境下)[通俗易懂]pycharm安装torch和cuda(在anaconda创建的新环境下)

    2025年7月29日
    2
  • ORA-12154:TNS:无法处理服务名

    ORA-12154:TNS:无法处理服务名环境:PLSQLDeveloper1332位,oracle9i310精简客户端32位因为PLSQLDeveloper1332位默认安装在C盘ProgramFiles(x86)下,就是因为这个路径问题导致会报这个错误,将PLSQLDeveloper安装在其他不包含中文,括号,空格的目录下即可。…

    2022年7月19日
    18

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号