1.oracle优化器种类html
自从ORACLE 10g以来,oracle就存在了两种优化器--CBO和RBO。sql
RBO: Rule-Based Optimization 基于规则的优化器数据库
CBO: Cost-Based Optimization 基于代价的优化器缓存
RBO顾名思义,oracle在系统内部定义了一系列sql语句执行了规则,sql严格按照规则来生成执行计划,并执行,对表的数据分布和变化不敏感,因此才有了CBO的出现。服务器
CBO是对每一个查询所耗费的资源进行量化,从而能够根据这个量化的值选出最佳的执行计划,一个查询所耗费的资源可分为:I/O,CPU,network三部分代价。网络
<1>I/O通常是将数据库文件中的数据库块读入内存(磁盘读入内存)所耗费的资源
session
<2>CPU代价是内存中处理数据的代价,在这些数据上进行排序sort,表的join链接操做,这都须要cpu资源的耗费。oracle
<3>network是远程查询数据库表或者执行分布式链接的网络传输代价分布式
注:oracle中数据库的概念是oracle数据文件中的最小单位,由多个操做系统块组成。ide
数据库使用的优化器根据参数optimizer_mode决定,取值以下:
RULE 使用RBO优化器
choose 数据字典有被引用的对象的统计数据,则使用CBO,不然使用RBO
all_rows 以数据吞吐量为主要目标,以便使用最少的资源完成语句
first_rows 以数据响应时间为主要目标,以便快速查询开始的n行数据
first_rows[1|100|1000|n] 让优化器选一个能把响应时间减到最小的执行计划,以迅速产生查询结果的前n行
2.执行计划中的概念
row_sources(行源) 根据where中条件限制后的结果集或者多表连接后的结果集,不单指table
predicate(谓词)
access谓词 这个谓词的条件的值将会影响数据的访问路径(通常针对索引)
fileter谓词 起过滤做用
driving table(驱动表,外表,outer table) 用于嵌套链接和哈希链接
probed table(被探查表,内表,inner table)
access path(访问路径)
full table scans(全表扫描) oracle顺序读取分配给表的每一个数据块,知道表的最高水位线。能够一次性读取多个块,block的数量则由操做系统的I/O最大值和multiblock(db_block_multiblock_read_count)参数共同决定
Table Access by ROWID(经过ROWID的表存取/rowid lookup)
Index Scan(索引扫描/index lookup)
......
sort-mergejoin(排序合并链接)
nested loop(嵌套链接)
hash join(哈希链接)
3.sql语句执行过程
每种类型sql语句都要一下n个阶段:
<1>create a cursor
<2>parse the statement解析语句
判断语法是否正确,权限是否充足,查找数据字典是否符合表,列的定义,锁分析,生成执行计划等,这一步骤比较耗费资源,通常都应该减小解析次数。可是也有下述这种状况:当sql的基表发生的dml语句致使数据分布发生了较大的变化(可能影响的执行计划),若是还采用以前的执行计划,有可能性能会不太好,这时候最好从新进行表分析,从新生成执行计划,因此这个仍是要看具体状况决定。
<5>bind any variables
<7>run the statement
<9>close the cursor
若使用了并行功能
<6>parallelize the statement 并行执行语句
如果select语句
<3>describe result of a query 描述查询结果集
<4>define output of a query 定义查询输出
<8>fetch rows of a query 获取查询行
4.sql中标的链接方式
排序合并链接
row_source1按照链接列进行排序,row_source2按照链接列进行排序
row_source1,row_source2一块儿执行合并操做,即将两个row_source按照链接条件链接起来
嵌套循环
通常原则是选择驱动表是较小的row_source
优势:能够快速返回已经链接的行,没必要等全部行链接操做处理完才返回数据,可实时响应
hash链接
较小的row_source用来构建hash table的bitmap,第二个row_source被用来hansed,并与第一个row_source生成的hash table匹配,以便进一步链接,比bitmap用来check hash table中是否有匹配的行。
三种链接方式比较:
smj:第一,对于非等值链接效率较高。关联列上有索引更好。对于两个较大的row_source比nl效率高
nl:第一快速响应。外部表较小,内部表上有惟一索引/高效的非惟一索引
hj:hash_area_size参数要合适。只能用于等值链接。
5.hints
/*+ ordered*/:form子句从左到右顺序链接
/*+ full(table)*/:全表扫描
/*+ index_ffs(table [index_name])*/:快速全表扫描
/*+ no_index(table [index])*/不使用索引
/*+ use_nl(table[,table...])*/ 嵌套循环
例:use_nl(a c)此时a是内部表,c是驱动表
此外有外关联的表不能做为驱动表。若外关联与ordered指定的顺序有冲突,则忽略ordered hint
6.trace的使用
SELECT ss.SID, ss.SERIAL#, --1.sid和serial#共同表示惟一一个session ss.USERNAME, --2.数据库用户名 ss.MACHINE, --3.链接数据库所在程序的机器名,以下图 ss.PROGRAM, --链接数据库的程序名 p.SPID as serverid,--与程序对应的server段的服务器进程号,在unix中较有用 ss.SERVER, --程序链接数据库模式:DEDICATED专用模式(trace只适用该模式)。shared --共享模式 ss.LOGON_TIME --链接数据库的登陆时间 FROM v$session ss, v$process p WHERE p.ADDR = ss.PADDR AND ss.USERNAME = 'SYS';
使用trace过程:
识别要跟踪的client程序到数据库的链接,上述sql可查
设定相应的parameter
time_statistics 收集trace信息时,是否收集时间信息,能够知道一个sql各阶段耗时状况
user_dump_dest 存放跟踪的文件位置
max_dump_file_size 配置跟踪文件的最大值
使用procedure设置参数
exec dbms_system.set_bool_param_in_session(sid => '65', seria# => '55', parnam => 'time_statistics', bval => true);
exec dbms_system.set_int_param_in_session(sid => '65', seria# => '55', parnam => 'user_dump_dest', intval => true)
3.启用跟踪功能
exec dbms_system.set_sql_trace_in_session(8,3,true);
4.run一段时间
5.关闭trace
exec dbms_system.set_sql_trace_in_session(8,3,false);
6.格式化文件
tkprof xxx.trc xx.out sys=no explain=scott/tiger
TKPROF filename1, filename2 [ SORT = [ opion][,option] ] [ PRINT = integer ] [ AGGREGATE = [ YES | NO ] ] [ INSERT = filename3 ] [ SYS = [ YES | NO ] ] [ [ TABLE = schema.table ] | [ EXPLAIN = user/password ] ] [ RECORD = filename ]
参数解析
SORT 在输出到输出文件前,先进程排序。若是省去,则按照实际使用的顺序输出到文件中。排序选项有如下多种: prscnt number of times parse was called prscpu cpu time parsing prsela elapsed time parsing prsdsk number of disk reads during parse prsqry number of buffers for consistent read during parse prscu number of buffers for current read during parse prsmis number of misses in library cache during parse execnt number of execute was called execpu cpu time spent executing exeela elapsed time executing exedsk number of disk reads during execute exeqry number of buffers for consistent read during execute execu number of buffers for current read during execute exerow number of rows processed during execute exemis number of library cache misses during execute fchcnt number of times fetch was called fchcpu cpu time spent fetching fchela elapsed time fetching fchdsk number of disk reads during fetch fchqry number of buffers for consistent read during fetch fchcu number of buffers for current read during fetch fchrow number of rows fetched userid userid of user that parsed the cursor
PRINT 只列出输出文件的第一个integer 的SQL语句。默认为全部的SQL语句。 AGGREGATE 若是= NO ,则不对多个相同的SQL进行汇总。 INSERT SQL 语句的一种,用于将跟踪文件的统计信息存储到数据库中。在TKPROF建立脚本后,在将结果输入到数据库中。 SYS 禁止或启用 将SYS用户所发布的SQL语句列表到输出文件中。 TABLE 在输出到输出文件前,用于存放临时表的用户名和表名。 EXPLAIN 对每条SQL 语句肯定其执行规划。并将执行规划写到输出文件中。 其中比较有用的一个排序选项是fchela,即按照elapsed time fetching来对分析的结果排序 (记住要设置初始化参数timed_statistics=true),生成的文件将把最消耗时间的sql放在最前面显示。 另一个有用的参数就是sys,这个参数设置为no能够阻止全部以sys用户执行的sql被显示出来, 这样能够减小分析出来的文件的复杂度,便于查看。
首先解释输出文件中列的含义: CALL:每次SQL语句的处理都分红三个部分 Parse:这步将SQL语句转换成执行计划,包括检查是否有正确的受权和所须要用到的表、列以及其余引用到的对象是否存在。 Execute:这步是真正的由Oracle来执行语句。对于insert、update、delete操做,这步会修改数据,对于select操做,这步就只是肯定选择的记录。 Fetch:返回查询语句中所得到的记录,这步只有select语句会被执行。 COUNT:这个语句被parse、execute、fetch的次数。 CPU:这个语句对于全部的parse、execute、fetch所消耗的cpu的时间,以秒为单位。 ELAPSED:这个语句全部消耗在parse、execute、fetch的总的时间。 DISK:从磁盘上的数据文件中物理读取的块的数量。通常来讲更想知道的是正在从缓存中读取的数据而不是从磁盘上读取的数据。 QUERY:在一致性读模式下,全部parse、execute、fetch所得到的buffer的数量。一致性模式的buffer是用于给一个长时间运行的事务提供一个一致性读的快照,缓存实际上在头部存储了状态。 CURRENT:在current模式下所得到的buffer的数量。通常在current模式下执行insert、update、delete操做都会获取buffer。在current模式下若是在高速缓存区发现有新的缓存足够给当前的事务使用,则这些buffer都会被读入了缓存区中。 ROWS: 全部SQL语句返回的记录数目,可是不包括子查询中返回的记录数目。对于select语句,返回记录是在fetch这步,对于insert、update、delete操做,返回记录则是在execute这步。
-----------------------------举例---------------------
tkprof是在cmd下执行!!