执行计划
一个SQL文本,经过解析,经过解析之后,oracle发现有很多种执行方案,然后oracle在这多种执行方案中,选出一种oracle认为最优的一种执行方案,来作为执行计划,然后oracle按照执行计划一步步去执行
因为oracle有多种的执行方案,但是,有的执行方案快,有的执行方案慢,有的执行方案效率高,有的执行方案效率低,有的执行方案消耗资源厉害,有的执行方案综合效率好,等等;oracle会选择最优的执行方案来作为执行计划
优化器
oracle数据库软件,里面最核心的一个组件:优化器(optimizer)
优化器平时做的事情(优化器的作用):
接到SQL文本以后,对SQL文本进行解析,然后生成执行计划,也就是负责对SQL文本的解析的
在数据库里面,有很多和优化器相关的参数
关于优化器有很多的参数,我们可以通过调整这些参数,来控制和调整优化器的一些工作方式,进一步来影响执行计划的生成
优化器在oracle各个版本中的变化
版本:
7.3.2、 7.3.4、 8i、 9i、 10g、 11g、 12c
7.3.2、7.3.4到8i,在8i里面开始出现了图形界面;
在7.3.2、7.3.4和8i的优化器的工作方式:RBO;
8i到9i,优化器发生了变化:在9i里面,优化器的工作方式:RBO或者CBO,可以选择;
10g以后的版本,优化器的工作方式:只能是CBO
RBO(rule based optimizer)基于规则的优化器
在RBO优化器里面存储着很多规则,然后根据规则,优化器来选择对应SQL文本的执行方案,然后生成执行计划
然而这有一个问题:对于SQL:select name from t where id = 5;
有规则:1、有where条件
2、id列,id列上有索引
3、‘ = ’
根据这些规则,RBO选择走索引,但是走索引效率一定好吗?
例如:t表有100万行,id = 5有90万行,这时候,走索引就不好了
在RBO时代,需要工程了解规则,写SQL的时候,需要按照规则来写,才能被解析出好的执行计划
CBO(cost based optimizer)基于成本的优化器
成本:CPU成本 + IO成本,主要成本是IO的成本
例如对于SQL:select name from t where id = 5;
把这个SQL给oracle,它会列出所有的执行路径;
然后估算出执行成本;
假如有两种方式(两个执行路径):
方式1:计算这个SQL需要多少CPU,需要多少IO,计算完了以后,它将CPU和IO折算成 => cost,假设cost = 150
方式2:计算这个SQL需要多少CPU,需要多少IO,计算完了以后,它将CPU和IO折算成 => cost,假设cost = 180
最后将cost低的作为执行计划,也就是将方式1作为执行计划
成本(cost)
对于SQL:select name from t where id = 5;
两个执行路径:
1、全表扫描:cost = 150
2、走索引:cost = 30
最后选择走索引
成本(cost)是以估算的方式算出来的
估算的依据(表和索引的统计信息):
1、t表:有多少行、有多少块、t表上id列的选择性
2、id列索引,索引的集群因子是多少
统计信息(statistics)
表和索引的统计信息
统计信息的特点:
它不是实时的(假设一个表有100万行数据,现在做一个inster,插入一行数据,变成100万+1行数据,它不会马上更新为100万+1行;)
表和索引的统计信息:影响着优化器生成执行计划,统计信息需要收集才有;不收集的话,这个统计信息就是旧的或者没有
统计信息的变化不是很大的时候,它对执行计划的生成不会造成很大的影响
收集统计信息,需要消耗大量的IO,而且还会带来别的一些影响,统计信息收集完了以后,oracle会把现有的shared pool里面的执行计划变得失效,让它重新去解析,会造成执行计划的不稳定,所以需要隔一段时候再收集一次统计信息,收集的不是那么的频繁;但是有一些情况是需要及时收集的,比如一个表发生过大批量的增删改以后,我们需要对这个表马上收集一下统计信息,才能使执行计划变得更准确一些
柱状图(histogram)
数据倾斜
数据倾斜:一个列上的值不多,这个列上的一个值或者某几个值的数量非常的少,而另外一个值非常的多
图:
数据倾斜的含义:
select ... from t where status = 0;这时候走索引好;select ... from t where status = 1;这时候全表扫描好
所以,当有以下几个条件的时候,我们就有必要收集柱状图:
1、一个表的一个列上有严重的数据倾斜;
2、这个列上有where条件;
3、这个列上有索引
柱状图属于统计信息
桶(bucket)
如何表示(展现)柱状图?
柱状图有一个桶(bucket)的概念,它用桶来表示这个柱状图,桶越多,执行计划越准确
图:
桶的数量最高为:254桶
数据字典
oracle数据库里面放着表,表呢分为两种:
1、数据字典表(dictionary)
2、生产表
生产表:比如一张表,里面记录着某种信息(比如员工的信息,员工的编号...)
数据字典表:记录着数据库里面的表,表的名字(1、tab$、 2、cost$、 3、user$等等);oracle数据库用表来记录数据库自身的信息(数据库有多少表、多少索引、多少函数、多少存储过程、权限等等信息),就是数据库用于自己管理自己的信息
oracle数据字典的类型:
1、字典表(tab$、cost$、user$):难看懂,因此在字典表的基础上,生成了一些视图
2、视图
3、x$表(x$bh):反应数据库实例实时的运行状态,这个x$bh也是很难看懂的
4、v$表:字典表和x$表结合推出了一个v$表(v$bh),v$bh反应的也是数据库实时的运行状态,并且好看一些
视图的分类:
1、dba_tables(整个数据库,所有用户下的所有的表)
2、user_tables(当前用户登录下的表,也就是使用当前登录用户所建的那些表)
3、all_tables(当前用户登录下,用户能够访问的所有表:用户所建的表和授权之后能够访问的表)