oracle执行计划相关
sql执行计划对于sql执行效率是至关重要的,所以对于程序开发人员和DBA而言,了解一下sql执行计划都是很有好处的。 什么是执行计划sql是一种声明性语言,它和我们平时常用的c,java这些命令性语言差别很大,声明性语言是告诉计算机我想要什么,而命令性语言是告诉计算机我想你这样去做。具体来讲,sql是告诉数据库系统,我要满足这些条件的数据,具体数据库系统怎么去获取sql想要的这些数据,就是数据库系统的事情了。 怎样获取执行计划执行计划根据是不是真实运行情况,我将执行计划分为预期执行计划和实际执行计划计划两种,explain plan得到的计划是根据当前的环境,统计等信息得出的,真正执行的时候是不是使用这个计划是不一定的(当然绝大部分情况,就是使用这个执行计划),实时计划就是真实运行中使用的计划。 explain plan(预期执行计划)如explain plan for select * from emp; sqlplus里的autotrace (实时计划)配置autotrace--以system用户登录sqlplus
sqlplus system/system_password@orcl
--然后执行脚本
@?rdbmsadminutlxplan
grant all on plan_table to public;
以sysdba登录sys用户
conn sys/sys_password as sysdba
--执行脚本
@?sqlplusadminplustrce
grant plustrace to public;
使用autotrace在sqlplus里执行一条sql语句前,使用以下命令控制autotrace set autot[race] off 关闭autotrace功能 set autot on 显示sql执行结果,执行计划,统计信息 set autot on explain 显示sql执行结果,执行计划 set autot on statistics 显示sql执行结果,统计信息 set autot traceonly 显示 执行计划,统计信息
sql跟踪(实时计划)准备 跟踪文件的路径 select t1.sid,t2.tracefile from v$session t1,v$process t2 where t1.paddr=t2.addr and t1.sid=xxx 其中xxx为从测试会话里获取的sid select distinct sid from v$mystat
或者查看v$process的spid,一般跟踪文件为sid_ora_spid.trc 使用alter session set tracefile_identifier=’xxxx’ 然后查找有该助记符的跟踪文件即可 启动跟踪的方法 2.使用dbms_monitor包 客户端标识符 允许跨越多个会话设置跟踪,使用dbms_session.set_identifier设置标识符,然后oracle会跟踪所有设置了该标识符的会话 实例 基于实例名 服务 指定一组相关的应用程序,使用dbms_service.create_service创建服务 模块名 开发人员在其程序代码里使用dbms_application_info.set_module设置该值 操作名 开发人员在程序代码里设置dbms_application_info.set_action设置该值 可以设置跟踪的内容 基于会话id和序列号设置跟踪 exec dbms_monitor.session_trace_enable(123,4567,true,false) exec dbms_monitor.session_trace_enable(null,null) 查看跟踪情况 使用tkprof工具转化跟踪文件为可读格式 理解执行计划执行计划主要有三个因素,访问路径,连接和执行顺序。 优化器访问路径访问路径指的是从数据库获取数据的方法。总体来说,索引访问路径在获取少量行时有用,全表扫描对于访问一个表里大部分行时更有效率。 优化器根据一下几个因素决定访问路径: 优化器首先根据查询语句里where子句和from子句决定那些访问路径是可用的。优化器使用可用的路径生成所有可能得执行计划,使用索引,列和表的统计信息,计算执行计划的成本,然后优化器选择成本最低的执行计划作为该语句的执行计划。 优化器访问路径有如下几种: 全表扫描(full table scans)全表扫描读取一个表的全部行然后使用过滤条件滤除不满足条件的数据。(全表扫描,会扫描高水位下的所有数据块)。全表扫描时,oracle顺序读取数据块,因为数据块是相邻的,所以数据库可以使用比单块读更加大的io调用。使用db_file_multiblock_read_count控制一次最大可以读取多少块。 有趣的是,全表扫描有可能比索引范围扫描更加的高效,这是因为在访问一个表大部分数据时,全表扫描可以使用更大的io调用,比多次小的io调用更加的高效。 优化器什么时候使用全表扫描 rowid扫描(rowid scans)rowid是一行数据的精确物理存储位置(在哪个数据文件,在数据文件的那个块,在数据块的哪一行),是获取一行数据的最快方式。 rowid扫描是先获取指定行的rowid(通过where条件过滤或者对索引的扫描),然后根据rowid定位选定的数据行。 优化器什么时候使用rowid扫描 索引扫描(index scans)索引扫描使用语句中的索引列的值在索引中查找一行数据的方法。oracle以两种方式使用索引扫描,一种是索引里包含了语句所需的所有信息,此时访问索引就够了,不需要再去访问表了。另一种是语句还需要表里其余列的信息,此时需要通过索引列值对应的rowid,再通过rowid扫描或者聚簇扫描访问相应的表,获取其余列的信息。 索引使用块io来评价而不是使用行oracle以块为单位进行io,故优化器 索引扫描方式
索引唯一扫描只返回一个rowid,当在语句中使用了unique索引或者主键约束的对应的列进行约束,确保只返回一行数据。这种扫描出现在语句中对unique索引或主键的所有列使用等号条件。
索引范围扫描是根据索引获取选定数据的一种常用方式。可以使用在unique索引或者非unique索引里。当order by或者group by里只有索引的列时,oracle会根据情况省略排序过程。 索引范围扫描出现在对索引里的列的范围查找情况。
和索引范围扫描相对应的方式,索引范围扫描是按升序进行扫描的,索引范围降序扫描是按降序。当语句里有对索引列的order by desc子句时。
索引跳跃扫描出现在使用组合索引时,在索引的前序列没有指定的情况下,使用了后续索引列。
省略一次排序操作,oracle使用索引全扫描时是使用单块读取进行io的。
查询包含的列全在索引列里,且至少一列有not null约束,快速全索引扫描只访问索引而不访问表,且oracle是以多块进行io的。该访问模式下不能省略order by子句
索引连接指的是若干个索引使用hash连接在一起,包含了查询所需的所有列,这样就不需要去访问表了,这种方式访问不能省略order by子句。
位图索引使用一个键值,然后使用映射函数将每一位转化为rowid。bitmap能够很方便的合并where里的多个条件。 聚簇访问(cluster access)oracle使用聚簇扫描从索引聚簇表里获取具有相同聚簇键值的数据行。在索引聚簇表里oracle将相同的聚簇键值的行被放在相同的数据块里。聚簇访问首先扫描聚簇索引获取指定行的rowid,然后使用rowid定位到指定行。 哈希访问(hash Access)oracle使用hash扫描在hash聚簇表里定位数据行。 抽样表扫描(sample table scans)抽样表扫描是从一个表或者select语句里获取抽样数据的访问方式。 表连接连接是语句从多个表里获取数据的一种方式。连接分为内连接和外连接两种。 对于一个有连接的语句,主要有三个因素影响执行计划的生成 嵌套循环连接(nested loop joins)优化器使用nested loop joins,当满足以下条件时: nested loop joins包含以下几个步骤: hash连接(hash joins)oracle使用hash joins来连接大数据集合,优化器选择两者中较小的表,在内存上使用连接键构造hash表,然后扫描较大的表,探测hash表找到连接行。 这种连接当较小的表可以在内存里放下时有最好的效果,这样成本被控制在两个表读取一次。 当满足连接使用等号连接,且满足下面两个条件之一 sort merge joinssort merge joins连接两个独立的行源,一般来说hash joins性能更好,但是如果满足以下两个条件时sort merge joins有更好的性能: sort merge joins一般用于不等连接条件时,对于大的数据集来说,性能优于nested loop joins。 sort merge joins由两个步骤组成, Cartesian joins没有连接条件时执行Cartesian joins,形成两个表的笛卡尔积集,用得很少。 outer joins外部连接扩展了简单连接的结果,包含满足连接条件的数据,同时包含部分或全部不满足条件的其中一个表的数据 nested loop outer joins在这种外连接,连接条件决定连接顺序,外层表是需要返回所有行的表,内层表是另一个表。 当满足以下条件时,使用这种连接方式: hash outer joins当满足以下条件时,优化器使用该连接方式: sort merge outer joins当nested loop outer joins和hash outer joins的成本都较高时,使用sort merge outer joins。 full outer joins全外连接相当于左连接和右连接的合集,包括满足连接条件的行,也包括不满足条件的所有行。 阅读执行计划执行计划里的步骤
执行计划里的每一行代表一个步骤,缩进越多的步骤越先执行,步骤id旁边有*的步骤在谓语信息段里有相应的谓语信息。 执行计划里的每一步返回一个行集,它的父亲步骤要么使用该行集要么是最后步骤,返回结果集。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |