精华内容
下载资源
问答
  • 看懂Oracle执行计划

    千次阅读 多人点赞 2018-03-06 11:46:06
    最近一直在跟Oracle打交道,从最初的一脸懵逼到现在的略有所知,也来总结一下自己最近所学,不定时更新ing… 一:什么是Oracle执行计划?执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述 二:怎样查看...

    最近一直在跟Oracle打交道,从最初的一脸懵逼到现在的略有所知,也来总结一下自己最近所学,不定时更新ing…

    一:什么是Oracle执行计划?

    执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述

    二:怎样查看Oracle执行计划?

    因为我一直用的PLSQL远程连接的公司数据库,所以这里以PLSQL为例:

    ①:配置执行计划需要显示的项:

    工具 —> 首选项 —> 窗口类型 —> 计划窗口 —> 根据需要配置要显示在执行计划中的列

    执行计划配置

    执行计划的常用列字段解释:

    基数(Rows):Oracle估计的当前操作的返回结果集行数

    字节(Bytes):执行该步骤后返回的字节数

    耗费(COST)、CPU耗费:Oracle估计的该步骤的执行成本,用于说明SQL执行的代价,理论上越小越好(该值可能与实际有出入)

    时间(Time):Oracle估计的当前操作所需的时间

    ②:打开执行计划:

    在SQL窗口执行完一条select语句后按 F5 即可查看刚刚执行的这条查询语句的执行计划

    执行计划查看

    注:在PLSQL中使用SQL命令查看执行计划的话,某些SQL*PLUS命令PLSQL无法支持,比如SET AUTOTRACE ON

    执行计划sql查看

    三:看懂Oracle执行计划

    看懂执行计划

    ①:执行顺序:

    根据Operation缩进来判断,缩进最多的最先执行;(缩进相同时,最上面的最先执行)

    例:上图中 INDEX RANGE SCAN 和 INDEX UNIQUE SCAN 两个动作缩进最多,最上面的 INDEX RANGE SCAN 先执行;

    同一级如果某个动作没有子ID就最先执行

    同一级的动作执行时遵循最上最右先执行的原则

    例:上图中 TABLE ACCESS BY GLOBAL INDEX ROWID 和 TABLE ACCESS BY INDEX ROWID 两个动作缩进都在同一级,则位于上面的 TABLE ACCESS BY GLOBAL INDEX ROWID 这个动作先执行;这个动作又包含一个子动作 INDEX RANGE SCAN,则位于右边的子动作 INDEX RANGE SCAN 先执行;

    图示中的SQL执行顺序即为:

    INDEX RANGE SCAN —> TABLE ACCESS BY GLOBAL INDEX ROWID —> INDEX UNIQUE SCAN —> TABLE ACCESS BY INDEX ROWID —> NESTED LOOPS OUTER —> SORT GROUP BY —> SELECT STATEMENT, GOAL = ALL_ROWS

    ( 注:PLSQL提供了查看执行顺序的功能按钮(上图中的红框部分) )

    ②:对图中动作的一些说明:

    1. 上图中 TABLE ACCESS BY … 即描述的是该动作执行时表访问(或者说Oracle访问数据)的方式;

    表访问的几种方式:(非全部)

    • TABLE ACCESS FULL(全表扫描)
    • TABLE ACCESS BY ROWID(通过ROWID的表存取)
    • TABLE ACCESS BY INDEX SCAN(索引扫描)

    (1) TABLE ACCESS FULL(全表扫描)

    Oracle会读取表中所有的行,并检查每一行是否满足SQL语句中的 Where 限制条件;

    全表扫描时可以使用多块读(即一次I/O读取多块数据块)操作,提升吞吐量;

    使用建议:数据量太大的表不建议使用全表扫描,除非本身需要取出的数据较多,占到表数据总量的 5% ~ 10% 或以上

    (2) TABLE ACCESS BY ROWID(通过ROWID的表存取) :

    先说一下什么是ROWID?

    rowid

    ROWID是由Oracle自动加在表中每行最后的一列伪列,既然是伪列,就说明表中并不会物理存储ROWID的值;

    你可以像使用其它列一样使用它,只是不能对该列的值进行增、删、改操作;

    一旦一行数据插入后,则其对应的ROWID在该行的生命周期内是唯一的,即使发生行迁移,该行的ROWID值也不变。

    让我们再回到 TABLE ACCESS BY ROWID 来:

    行的ROWID指出了该行所在的数据文件、数据块以及行在该块中的位置,所以通过ROWID可以快速定位到目标数据上,这也是Oracle中存取单行数据最快的方法;

    (3) TABLE ACCESS BY INDEX SCAN(索引扫描)

    在索引块中,既存储每个索引的键值,也存储具有该键值的行的ROWID。

    一个数字列上建索引后该索引可能的概念结构如下图:

    index

    所以索引扫描其实分为两步:

    Ⅰ:扫描索引得到对应的ROWID

    Ⅱ:通过ROWID定位到具体的行读取数据

    ----------------索引扫描延伸-------------------

    索引扫描又分五种:

    • INDEX UNIQUE SCAN(索引唯一扫描)
    • INDEX RANGE SCAN(索引范围扫描)
    • INDEX FULL SCAN(索引全扫描)
    • INDEX FAST FULL SCAN(索引快速扫描)
    • INDEX SKIP SCAN(索引跳跃扫描)

    a) INDEX UNIQUE SCAN(索引唯一扫描)

    针对唯一性索引(UNIQUE INDEX)的扫描,每次至多只返回一条记录;

    表中某字段存在 UNIQUE、PRIMARY KEY 约束时,Oracle常实现唯一性扫描;

    b) INDEX RANGE SCAN(索引范围扫描)

    使用一个索引存取多行数据;

    发生索引范围扫描的三种情况:

    • 在唯一索引列上使用了范围操作符(如:> < <> >= <= between)
    • 在组合索引上,只使用部分列进行查询(查询时必须包含前导列,否则会走全表扫描)
    • 对非唯一索引列上进行的任何查询

    c) INDEX FULL SCAN(索引全扫描)

    进行全索引扫描时,查询出的数据都必须从索引中可以直接得到(注意全索引扫描只有在CBO模式下才有效)

    ----------------------- 延伸阅读:Oracle优化器简述 -----------------------

    Oracle中的优化器是SQL分析和执行的优化工具,它负责生成、制定SQL的执行计划。

    Oracle的优化器有两种:

    • RBO(Rule-Based Optimization) 基于规则的优化器
    • CBO(Cost-Based Optimization) 基于代价的优化器

    RBO:

    RBO有严格的使用规则,只要按照这套规则去写SQL语句,无论数据表中的内容怎样,也不会影响到你的执行计划;

    换句话说,RBO对数据“不敏感”,它要求SQL编写人员必须要了解各项细则;

    RBO一直沿用至ORACLE 9i,从ORACLE 10g开始,RBO已经彻底被抛弃。

    CBO:

    CBO是一种比RBO更加合理、可靠的优化器,在ORACLE 10g中完全取代RBO;

    CBO通过计算各种可能的执行计划的“代价”,即COST,从中选用COST最低的执行方案作为实际运行方案;

    它依赖数据库对象的统计信息,统计信息的准确与否会影响CBO做出最优的选择,也就是对数据“敏感”。

    ---------------------------------------------------------------------

    d) INDEX FAST FULL SCAN(索引快速扫描):

    扫描索引中的所有的数据块,与 INDEX FULL SCAN 类似,但是一个显著的区别是它不对查询出的数据进行排序(即数据不是以排序顺序被返回)

    e) INDEX SKIP SCAN(索引跳跃扫描)

    Oracle 9i后提供,有时候复合索引的前导列(索引包含的第一列)没有在查询语句中出现,oralce也会使用该复合索引,这时候就使用的INDEX SKIP SCAN;

    什么时候会触发 INDEX SKIP SCAN 呢?

    前提条件:表有一个复合索引,且在查询时有除了前导列(索引中第一列)外的其他列作为条件,并且优化器模式为CBO时

    当Oracle发现前导列的唯一值个数很少时,会将每个唯一值都作为常规扫描的入口,在此基础上做一次查找,最后合并这些查询;

    例如:

    假设表emp有ename(雇员名称)、job(职位名)、sex(性别)三个字段,并且建立了如 create index idx_emp on emp (sex, ename, job) 的复合索引;

    因为性别只有 '男' 和 '女' 两个值,所以为了提高索引的利用率,Oracle可将这个复合索引拆成 ('男', ename, job),('女', ename, job) 这两个复合索引;

    当查询 select * from emp where job = 'Programmer' 时,该查询发出后:

    Oracle先进入sex为'男'的入口,这时候使用到了 ('男', ename, job) 这条复合索引,查找 job = 'Programmer' 的条目;

    再进入sex为'女'的入口,这时候使用到了 ('女', ename, job) 这条复合索引,查找 job = 'Programmer' 的条目;

    最后合并查询到的来自两个入口的结果集。

    ----------------------------------------------

    2. 上图中的 NESTED LOOPS … 描述的是表连接方式;

    JOIN 关键字用于将两张表作连接,一次只能连接两张表,JOIN 操作的各步骤一般是串行的(在读取做连接的两张表的数据时可以并行读取);

    表(row source)之间的连接顺序对于查询效率有很大的影响,对首先存取的表(驱动表)先应用某些限制条件(Where过滤条件)以得到一个较小的row source,可以使得连接效率提高。

    -------------------------延伸阅读:驱动表(Driving Table)与匹配表(Probed Table)-------------------------

    驱动表(Driving Table):

    表连接时首先存取的表,又称外层表(Outer Table),这个概念用于 NESTED LOOPS(嵌套循环) 与 HASH JOIN(哈希连接)中;

    如果驱动表返回较多的行数据,则对所有的后续操作有负面影响,故一般选择小表(应用Where限制条件后返回较少行数的表)作为驱动表。

    匹配表(Probed Table):

    又称为内层表(Inner Table),从驱动表获取一行具体数据后,会到该表中寻找符合连接条件的行。故该表一般为大表(应用Where限制条件后返回较多行数的表)。

    ---------------------------------------------------------------------------------------------------------

    表连接的几种方式:

    • SORT MERGE JOIN(排序-合并连接)
    • NESTED LOOPS(嵌套循环)
    • HASH JOIN(哈希连接)
    • CARTESIAN PRODUCT(笛卡尔积)

    注:这里将首先存取的表称作 row source 1,将之后参与连接的表称作 row source 2

    (1) SORT MERGE JOIN(排序-合并连接)

    假设有查询:select a.name, b.name from table_A a join table_B b on (a.id = b.id)

    内部连接过程:

    a) 生成 row source 1 需要的数据,按照连接操作关联列(如示例中的a.id)对这些数据进行排序

    b) 生成 row source 2 需要的数据,按照与 a) 中对应的连接操作关联列(b.id)对数据进行排序

    c) 两边已排序的行放在一起执行合并操作(对两边的数据集进行扫描并判断是否连接)

    延伸:

    如果示例中的连接操作关联列 a.id,b.id 之前就已经被排过序了的话,连接速度便可大大提高,因为排序是很费时间和资源的操作,尤其对于有大量数据的表。

    故可以考虑在 a.id,b.id 上建立索引让其能预先排好序。不过遗憾的是,由于返回的结果集中包括所有字段,所以通常的执行计划中,即使连接列存在索引,也不会进入到执行计划中,除非进行一些特定列处理(如仅仅只查询有索引的列等)。

    排序-合并连接的表无驱动顺序,谁在前面都可以;

    排序-合并连接适用的连接条件有: < <= = > >= ,不适用的连接条件有: <> like

    (2) NESTED LOOPS(嵌套循环)

    内部连接过程:

    a) 取出 row source 1 的 row 1(第一行数据),遍历 row source 2 的所有行并检查是否有匹配的,取出匹配的行放入结果集中

    b) 取出 row source 1 的 row 2(第二行数据),遍历 row source 2 的所有行并检查是否有匹配的,取出匹配的行放入结果集中

    c) ……

    若 row source 1 (即驱动表)中返回了 N 行数据,则 row source 2 也相应的会被全表遍历 N 次。

    因为 row source 1 的每一行都会去匹配 row source 2 的所有行,所以当 row source 1 返回的行数尽可能少并且能高效访问 row source 2(如建立适当的索引)时,效率较高。

    延伸:

    嵌套循环的表有驱动顺序,注意选择合适的驱动表。

    嵌套循环连接有一个其他连接方式没有的好处是:可以先返回已经连接的行,而不必等所有的连接操作处理完才返回数据,这样可以实现快速响应。

    应尽可能使用限制条件(Where过滤条件)使驱动表(row source 1)返回的行数尽可能少,同时在匹配表(row source 2)的连接操作关联列上建立唯一索引(UNIQUE INDEX)或是选择性较好的非唯一索引,此时嵌套循环连接的执行效率会变得很高。若驱动表返回的行数较多,即使匹配表连接操作关联列上存在索引,连接效率也不会很高。

    (3)HASH JOIN(哈希连接) :

    哈希连接只适用于等值连接(即连接条件为 = )

    HASH JOIN对两个表做连接时并不一定是都进行全表扫描,其并不限制表访问方式;

    内部连接过程简述:

    a) 取出 row source 1(驱动表,在HASH JOIN中又称为Build Table) 的数据集,然后将其构建成内存中的一个 Hash Table(Hash函数的Hash KEY就是连接操作关联列),创建Hash位图(bitmap)

    b) 取出 row source 2(匹配表)的数据集,对其中的每一条数据的连接操作关联列使用相同的Hash函数并找到对应的 a) 里的数据在 Hash Table 中的位置,在该位置上检查能否找到匹配的数据

    ----------------延伸阅读:Hash Table相关----------------

    来自Wiki的解释:

    In computing, a hash table (hash map) is a data structure used to implement an associative array, a structure that can map keys to values. A hash table uses a hash function to compute an index into an array of buckets or slots, from which the desired value can be found.

    散列(hash)技术:在记录的存储位置和记录具有的关键字key之间建立一个对应关系 f ,使得输入key后,可以得到对应的存储位置 f(key),这个对应关系 f 就是散列(哈希)函数;

    采用散列技术将记录存储在一块连续的存储空间中,这块连续的存储空间就是散列表(哈希表);

    不同的key经同一散列函数散列后得到的散列值理论上应该不同,但是实际中有可能相同,相同时即是发生了散列(哈希)冲突,解决散列冲突的办法有很多,比如HashMap中就是用链地址法来解决哈希冲突;

    哈希表是一种面向查找的数据结构,在输入给定值后查找给定值对应的记录在表中的位置以获取特定记录这个过程的速度很快。

    --------------------------------------------------------

    HASH JOIN的三种模式:

    • OPTIMAL HASH JOIN
    • ONEPASS HASH JOIN
    • MULTIPASS HASH JOIN

    1) OPTIMAL HASH JOIN

    OPTIMAL 模式是从驱动表(也称Build Table)上获取的结果集比较小,可以把根据结果集构建的整个Hash Table都建立在用户可以使用的内存区域里。

    optimal_hash_join

    连接过程简述:

    Ⅰ:首先对Build Table内各行数据的连接操作关联列使用Hash函数,把Build Table的结果集构建成内存中的Hash Table。如图所示,可以把Hash Table看作内存中的一块大的方形区域,里面有很多的小格子,Build Table里的数据就分散分布在这些小格子中,而这些小格子就是Hash Bucket(见上面Wiki的定义)。

    Ⅱ:开始读取匹配表(Probed Table)的数据,对其中每行数据的连接操作关联列都使用同上的Hash函数,定位Build Table里使用Hash函数后具有相同值数据所在的Hash Bucket。

    Ⅲ:定位到具体的Hash Bucket后,先检查Bucket里是否有数据,没有的话就马上丢掉匹配表(Probed Table)的这一行。如果里面有数据,则继续检查里面的数据(驱动表的数据)是否和匹配表的数据相匹配。

    2): ONEPASS HASH JOIN :

    从驱动表(也称Build Table)上获取的结果集较大,无法将根据结果集构建的Hash Table全部放入内存中时,会使用 ONEPASS 模式。

    one_pass_hash_join

    连接过程简述:

    Ⅰ:对Build Table内各行数据的连接操作关联列使用Hash函数,根据Build Table的结果集构建Hash Table后,由于内存无法放下所有的Hash Table内容,将导致有的Hash Bucket放在内存里,有的Hash Bucket放在磁盘上,无论放在内存里还是磁盘里,Oracle都使用一个Bitmap结构来反映这些Hash Bucket的状态(包括其位置和是否有数据)。

    Ⅱ:读取匹配表数据并对每行的连接操作关联列使用同上的Hash函数,定位Bitmap上Build Table里使用Hash函数后具有相同值数据所在的Bucket。如果该Bucket为空,则丢弃匹配表的这条数据。如果不为空,则需要看该Bucket是在内存里还是在磁盘上。

    如果在内存中,就直接访问这个Bucket并检查其中的数据是否匹配,有匹配的话就返回这条查询结果。

    如果在磁盘上,就先把这条待匹配数据放到一边,将其先暂存在内存里,等以后积累了一定量的这样的待匹配数据后,再批量的把这些数据写入到磁盘上(上图中的 Dump probe partitions to disk)。

    Ⅲ:当把匹配表完整的扫描了一遍后,可能已经返回了一部分匹配的数据了。接下来还有Hash Table中一部分在磁盘上的Hash Bucket数据以及匹配表中部分被写入到磁盘上的待匹配数据未处理,现在Oracle会把磁盘上的这两部分数据重新匹配一次,然后返回最终的查询结果。

    3): MULTIPASS HASH JOIN

    当内存特别小或者相对而言Hash Table的数据特别大时,会使用 MULTIPASS 模式。MULTIPASS会多次读取磁盘数据,应尽量避免使用该模式。

    3. 上图中的 … OUTER 描述的是表连接类型;

    表连接的两种类型:

    • INNER JOIN(内连接)
    • OUTER JOIN(外连接)

    示例数据说明:

    现有A、B两表,A表信息如下:

    table_A

    B表信息如下:

    table_B

    下面的例子都用A、B两表来演示。

    (1) INNER JOIN(内连接)

    只返回两表中相匹配的记录

    INNER JOIN 又分为两种:

    • 等值连接(连接条件为 =
    • 非等值连接(连接条件为 非 = ,如 > >= < <= 等)

    等值连接用的最多,下面以等值连接举例:

    内连接的两种写法:

    Ⅰ: select a.id A_ID, a.name A_NAME, b.id B_ID, b.name B_NAME from A a inner join B b on (a.id = b.id)

    Ⅱ: select a.id A_ID, a.name A_NAME, b.id B_ID, b.name B_NAME from A a join B b on (a.id = b.id)

    连接时只返回满足连接条件(a.id = b.id)的记录:

    inner_join

    (2) OUTER JOIN(外连接)

    OUTER JOIN 分为三种:

    • LEFT OUTER JOIN(可简写为 LEFT JOIN,左外连接)
    • RIGHT OUTER JOIN( RIGHT JOIN,右外连接)
    • FULL OUTER JOIN( FULL JOIN,全外连接)

    a) LEFT JOIN(左连接)

    返回的结果不仅包含符合连接条件的记录,还包含左边表中的全部记录。(若返回的左表中某行记录在右表中没有匹配项,则右表中的返回列均为空值)

    两种写法:

    Ⅰ:select a.id A_ID, a.name A_NAME, b.id B_ID, b.name B_NAME from A a left outer join B b on (a.id = b.id)

    Ⅱ:select a.id A_ID, a.name A_NAME, b.id B_ID, b.name B_NAME from A a left join B b on (a.id = b.id)

    返回结果:

    left_join

    b) RIGHT JOIN(右连接)

    返回的结果不仅包含符合连接条件的记录,还包含右边表中的全部记录。(若返回的右表中某行记录在左表中没有匹配项,则左表中的返回列均为空值)

    两种写法:

    Ⅰ:select a.id A_ID, a.name A_NAME, b.id B_ID, b.name B_NAME from A a right outer join B b on (a.id = b.id)

    Ⅱ:select a.id A_ID, a.name A_NAME, b.id B_ID, b.name B_NAME from A a right join B b on (a.id = b.id)

    返回结果:

    right_join

    c) FULL JOIN(全连接)

    返回左右两表的全部记录。(左右两边不匹配的项都以空值代替)

    两种写法:

    Ⅰ:select a.id A_ID, a.name A_NAME, b.id B_ID, b.name B_NAME from A a full outer join B b on (a.id = b.id)

    Ⅱ:select a.id A_ID, a.name A_NAME, b.id B_ID, b.name B_NAME from A a full join B b on (a.id = b.id)

    返回结果:

    full_join

    ---------------------延伸阅读: (+) 操作符-------------------

    (+) 操作符是Oracle特有的表示法,用来表示外连接(只能表示 左外、右外 连接),需要配合Where语句使用。

    特别注意:(+) 操作符在左表的连接条件上表示右连接,在右表的连接条件上表示左连接

    如:

    Ⅰ:select a.id A_ID, a.name A_NAME, b.id B_ID, b.name B_NAME from A a, B b where a.id = b.id(+)

    查询结果:

    右边( )

    实际与左连接 select a.id A_ID, a.name A_NAME, b.id B_ID, b.name B_NAME from A a left join B b on (a.id = b.id) 效果等价

    Ⅱ:select a.id A_ID, a.name A_NAME, b.id B_ID, b.name B_NAME from A a, B b where a.id(+) = b.id

    查询结果:

    左边( )

    实际与右连接 select a.id A_ID, a.name A_NAME, b.id B_ID, b.name B_NAME from A a right join B b on (a.id = b.id) 效果等价

    展开全文
  • Oracle执行计划Explain Plan 如何使用

    千次阅读 2019-01-11 21:26:33
    Oracle执行计划Explain Plan 1.1 概念 概念:一条查询语句在ORACLE中的执行过程或访问路径的描述。即就是对一个查询任务,做出一份怎样去完成任务的详细方案。 如果要分析某条SQL的性能问题,通常我们要先看SQL的...

    1 . Oracle执行计划Explain Plan

    1.1 概念

    概念:一条查询语句在ORACLE中的执行过程或访问路径的描述。即就是对一个查询任务,做出一份怎样去完成任务的详细方案。

    如果要分析某条SQL的性能问题,通常我们要先看SQL的执行计划,看看SQL的每一步执行是否存在问题。 看懂执行计划也就成了SQL优化的先决条件。 通过执行计划定位性能问题,定位后就通过建立索引、修改sql等解决问题。

    1.2 查看工具

    在这里插入图片描述

    1.3 如何读懂执行计划

    1.3.1 执行顺序的原则

    执行顺序的原则是:由上至下,从右向左
    由上至下:在执行计划中一般含有多个节点,相同级别(或并列)的节点,靠上的优先执行,靠下的后执行
    从右向左:在某个节点下还存在多个子节点,先从最靠右的子节点开始执行。

    一般按缩进长度来判断,缩进最大的最先执行,如果有2行缩进一样,那么就先执行上面的。

    1.3.2 执行计划中字段解释

    ID: 一个序号,但不是执行的先后顺序。执行的先后根据缩进来判断。

    Operation: 当前操作的内容。

    Rows: 当前操作的Cardinality,Oracle估计当前操作的返回结果集。

    Cost(CPU):Oracle 计算出来的一个数值(代价),用于说明SQL执行的代价。

    Time:Oracle 估计当前操作的时间。

    以下推荐个人文章
    [亲测]Oracle数据库安装与配置

    [亲测]Oracle数据库操作

    [亲测]Oracle表的创建、修改与删除

    [亲测]Oracle数据库约束

    [亲测]Oracle数据增删改

    [亲测]Oracle查询–单表查询,连接查询(一)

    [亲测]Oracle查询–子查询,分页查询(二)

    [亲测]Oracle查询–单行函数–PL/SQL,分析函数,集合运算(三)

    Oracle执行计划Explain Plan 如何使用

    [亲测]数据库优化

    展开全文
  • Oracle执行计划——查看执行计划的方法

    万次阅读 多人点赞 2018-09-12 17:17:43
    执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述。 (2)执行计划的选择 通常一条SQL有多个执行计划,那我们如何选择?那种执行开销更低,就意味着性能更好,速度更快,我们就选哪一种,这个过程叫做...

    (1)什么是执行计划
    SQL是一种傻瓜式语言,每一个条件就是一个需求,访问的顺序不同就形成了不同的执行计划。Oracle必须做出选择,一次只能有一种访问路径。执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述


    (2)执行计划的选择

    通常一条SQL有多个执行计划,那我们如何选择?那种执行开销更低,就意味着性能更好,速度更快,我们就选哪一种,这个过程叫做Oracle的解析过程,然后Oracle会把更好的执行计划放到SGA的Shared Pool里,后续再执行同样的SQL只需在Shared Pool里获取就行了,不需要再去分析


    (3)执行计划选定依据

    根据统计信息来选择执行计划。


    (4)统计信息
    什么是统计信息: 记录数、块数等,具体查看dba_tables / dba_indexes


    (5)动态采样

    Oracle正常情况下会在每天的某段时间收集统计信息,对于新建的表,Oracl如何收集统计信息?采用动态采样。
    set autotrace on
    set linesize 1000
    --执行SQL语句
    --会出现dynamic sampling used for this statement(level=2)关键


     

    (一)六种执行计划

    Oracle提供了6种执行计划获取方法,各种方法侧重点不同:

    选择时一般遵循以下规则:
    1.如果sql执行很长时间才出结果或返回不了结果,用方法1:explain plan for
    2.跟踪某条sql最简单的方法是方法1:explain plan for,其次是方法2:set autotrace on
    3.如果相关察某个sql多个执行计划的情况,只能用方法4:dbms_xplan.display_cursor或方法6:awrsqrpt.sql
    4.如果sql中含有函数,函数中有含有sql,即存在多层调用,想准确分析只能用方法5:10046追踪
    5.想法看到真实的执行计划,不能用方法1:explain plan for和方法2:set autotrace on
    6.想要获取表被访问的次数,只能用方法3:statistics_level = all

    获取方法 优点 缺点

    [explain plan for] plsql按F5

     

    explain plan for select * from dual;

    select * from table(dbms_xplan.display());

    无需真正执行,快捷方便 1.没有输出相关统计信息,例如产生了多少逻辑读,多少次物理读,多少次递归调用的情况;
    2.无法判断处理了多少行;
    3.无法判断表执行了多少次

    [set autotrace on]-sql*plus

     

    set autotrace on

    select * from dual;

    1.可以输出运行时的相关统计信息(产生多少逻辑读、多少次递归调用、多少次物理读等);

    2.虽然要等语句执行完才能输出执行计划,但是可以有traceonly开关来控制返回结果不打屏输出

    1.必须要等SQL语句执行完,才出结果

    2.无法看到表被访问了多少次;

    [statistics_level=all]

     

    alter session set statistics_level=all;

    select * from dual;

    select * from table(dbms_xplan.display_cursor(‘sql_id/hash_value’,null,'allstats last'));

    1.可以清晰的从starts得出表被访问多少次;

    2.可以从E-Rows和A-Rows得到预测的行数和真实的行数,从而可以准确判断Oracle评估是否准确;

    3.虽然没有准确的输出运行时的相关统计信息,但是执行计划中的Buffers就是真实的逻辑读的数值;

    1.必须要等执行完后才能输出结果;

    2.无法控制结果打屏输出,不像autotrace可以设置traceonly保证不输出结果;

    3.看不出递归调用,看不出物理读的数值

    [dbms_xplan.display_cursor]

     

    select * from table( dbms_xplan.display_cursor('&sql_id') );

    1.知道sql_id即可得到执行计划,与explain plan for一样无需执行;

    2.可得到真实的执行计划

    1.没有输出运行的统计相关信息;

    2.无法判断处理了多少行;

    3.无法判断表被访问了多少次;

    [事件10046 trace]

     

    步骤1:alter session set events '10046 trace name context forever,level 12'; --开启追踪
    步骤2:执行sql语句;
    步骤3:alter session set events '10046 trace name context off'; --关闭追踪
    步骤4:找到跟踪后产生的文件(开启10046前先用‘ls -lrt’看一下文件,执行结束后再看哪个是多出来的文件即可)
    步骤5:tkprof trc文件 目标文件 sys=no sort=prsela,exeela,fchela --格式化命令

    1.可以看出sql语句对应的等待事件;

    2.如果函数中有sql调用,函数中有包含sql,将会被列出,无处遁形;

    3.可以方便的看处理的行数,产生的逻辑物理读;

    4.可以方便的看解析时间和执行时间;

    5.可以跟踪整个程序包

    1.步骤繁琐;

    2.无法判断表被访问了多少次;

    3.执行计划中的谓词部分不能清晰的展现出来

     

     

     


    附录:


    (0)Oracle如何收集统计信息

    ① Oracle会选择在一个特定的时间段收集表和索引的统计信息(默认周一至周五:22:00,周六周日:06:00),用户可自行调整,主要为了避开高峰期;
    ② 表与索引的分析有阈值限制,超过阈值才会自动进行分析。如果数据变化量不大,Oracle是不会去分析的;
    ③ 收集方式灵活。可针对分区表的某个分区进行,可采用并行机制来收集表和索引的信息;


    如何收集统计信息
    --收集表统计信息

    exec dbms_stats.gather_table_stats(ownname => 'AAA', tabname => 'TEST02',estimate_percent =>
    10,method_opt => 'for all indexed columns');

    --收集索引统计信息

    exec dbms_stats.gather_index_stats(ownname => 'AAA',indname => 'ID_IDX',estimate_percent =>
    10,degree => '4');

    --收集表与索引的统计信息

    exec dbms_stats.gather_table_stats(ownname => 'AAA',tabname => 'TEST02',estimate_percent =>
    10,method_opt => 'for all indexed columns',cascade => true);

    (1)explain plan for

    SQL> show user
         USER 为 "HR"
    SQL> set linesize 1000
    SQL> set pagesize 2000
    SQL> explain plan for
    2 select *
    3 from employees,jobs
    4 where employees.job_id=jobs.job_id
    5 and employees.department_id=50;
    已解释。
    
    SQL> select * from table(dbms_xplan.display());
    
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------
    ----------------------------------------------------
    Plan hash value: 303035560
    ------------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    ------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 45 | 4590 | 6 (17)| 00:00:01 |
    | 1 | MERGE JOIN | | 45 | 4590 | 6 (17)| 00:00:01 |
    | 2 | TABLE ACCESS BY INDEX ROWID| JOBS | 19 | 627 | 2 (0)| 00:00:01 |
    | 3 | INDEX FULL SCAN | JOB_ID_PK | 19 | | 1 (0)| 00:00:01 |
    |* 4 | SORT JOIN | | 45 | 3105 | 4 (25)| 00:00:01 |
    |* 5 | TABLE ACCESS FULL | EMPLOYEES | 45 | 3105 | 3 (0)| 00:00:01 |
    ------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    4 - access("EMPLOYEES"."JOB_ID"="JOBS"."JOB_ID")
    filter("EMPLOYEES"."JOB_ID"="JOBS"."JOB_ID")
    5 - filter("EMPLOYEES"."DEPARTMENT_ID"=50)
    已选择19行。

    优点:无需真正执行,快捷方便
    缺点:1.没有输出相关统计信息,例如产生了多少逻辑读,多少次物理读,多少次递归调用的情况;
    2.无法判断处理了多少行;
    3.无法判断表执行了多少次
     


    (2)set autotrace on

    用法:
    命令作用
    SET AUTOT[RACE] OFF 停止AutoTrace
    SET AUTOT[RACE] ON 开启AutoTrace,显示AUTOTRACE信息和SQL执行结果
    SET AUTOT[RACE] TRACEONLY 开启AutoTrace,仅显示AUTOTRACE信息
    SET AUTOT[RACE] ON EXPLAIN 开启AutoTrace,仅显示AUTOTRACE的EXPLAIN信息
    SET AUTOT[RACE] ON STATISTICS 开启AutoTrace,仅显示AUTOTRACE的STATISTICS信息

    SQL> set autotrace on
    SQL> select * from employees,jobs where employees.job_id=jobs.job_id and employees.department_id=50;
    --输出结果(略)
    -- ...
    已选择45行。
    
    执行计划
    ----------------------------------------------------------
    Plan hash value: 303035560
    ------------------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
    ------------------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | 45 | 4590 | 6 (17)| 00:00:01 |
    | 1 | MERGE JOIN | | 45 | 4590 | 6 (17)| 00:00:01 |
    | 2 | TABLE ACCESS BY INDEX ROWID| JOBS | 19 | 627 | 2 (0)| 00:00:01 |
    | 3 | INDEX FULL SCAN | JOB_ID_PK | 19 | | 1 (0)| 00:00:01 |
    |* 4 | SORT JOIN | | 45 | 3105 | 4 (25)| 00:00:01 |
    |* 5 | TABLE ACCESS FULL | EMPLOYEES | 45 | 3105 | 3 (0)| 00:00:01 |
    ------------------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    4 - access("EMPLOYEES"."JOB_ID"="JOBS"."JOB_ID")
    filter("EMPLOYEES"."JOB_ID"="JOBS"."JOB_ID")
    5 - filter("EMPLOYEES"."DEPARTMENT_ID"=50)
    统计信息
    ----------------------------------------------------------
    0 recursive calls
    0 db block gets
    13 consistent gets
    0 physical reads
    0 redo size
    5040 bytes sent via SQL*Net to client
    433 bytes received via SQL*Net from client
    4 SQL*Net roundtrips to/from client
    1 sorts (memory)
    0 sorts (disk)
    45 rows processed

    优点:1.可以输出运行时的相关统计信息(产生多少逻辑读、多少次递归调用、多少次物理读等);
                2.虽然要等语句执行完才能输出执行计划,但是可以有traceonly开关来控制返回结果不打屏输出
    缺点:1.必须要等SQL语句执行完,才出结果;
                2.无法看到表被访问了多少次;


    (3)statistics_level=all

    步骤一:ALTER SESSION SET STATISTICS_LEVEL=ALL;
    步骤二:执行待分析的SQL
    步骤三:select * from table(dbms_xplan.display_cursor(‘sql_id/hash_value’,null,'allstats last'));

    SQL> alter session set statistics_level=all;
    SQL> select * from employees,jobs where employees.job_id=jobs.job_id and employees.department_id=50;
    --输出结果
    --...
    已选择45行。
    
    SQL> set linesize 1000
    SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));
    
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------
    -----------
    SQL_ID d8jzhcdwmd9ut, child number 0
    -------------------------------------
    select * from employees,jobs where employees.job_id=jobs.job_id and
    employees.department_id=50
    Plan hash value: 303035560
    ------------------------------------------------------------------------------------------------------------------------
    ----------------
    | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem |
    1Mem | Used-Mem |
    ------------------------------------------------------------------------------------------------------------------------
    ----------------
    | 0 | SELECT STATEMENT | | 1 | | 45 |00:00:00.01 | 13 | 8 | |
    | |
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------
    -------------
    | 1 | MERGE JOIN | | 1 | 45 | 45 |00:00:00.01 | 13 | 8 | |
    | |
    | 2 | TABLE ACCESS BY INDEX ROWID| JOBS | 1 | 19 | 19 |00:00:00.01 | 6 | 2 | |
    | |
    | 3 | INDEX FULL SCAN | JOB_ID_PK | 1 | 19 | 19 |00:00:00.01 | 3 | 1 | |
    | |
    |* 4 | SORT JOIN | | 19 | 45 | 45 |00:00:00.01 | 7 | 6 | 6144 |
    6144 | 6144 (0)|
    |* 5 | TABLE ACCESS FULL | EMPLOYEES | 1 | 45 | 45 |00:00:00.01 | 7 | 6 | |
    | |
    ------------------------------------------------------------------------------------------------------------------------
    ----------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    4 - access("EMPLOYEES"."JOB_ID"="JOBS"."JOB_ID")
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------
    -----
    filter("EMPLOYEES"."JOB_ID"="JOBS"."JOB_ID")
    5 - filter("EMPLOYEES"."DEPARTMENT_ID"=50)
    已选择25行。

    关键字解读:
    1.starts:SQL执行的次数;
    2.E-Rows:执行计划预计返回的行数;
    3.R-Rows:执行计划实际返回的行数;
    4.A-Time:每一步执行的时间(HH:MM:SS.FF),根据这一行可知SQL耗时在哪些地方;
    5.Buffers:每一步实际执行的逻辑读或一致性读;
    6.Reads:物理读;

    优点:1.可以清晰的从starts得出表被访问多少次
                2.可以从E-Rows和A-Rows得到预测的行数和真实的行数,从而可以准确判断Oracle评估是否准确
                3.虽然没有准确的输出运行时的相关统计信息,但是执行计划中的Buffers就是真实的逻辑读的数值
    缺点:1.必须要等执行完后才能输出结果;
                2.无法控制结果打屏输出,不像autotrace可以设置traceonly保证不输出结果;
                3.看不出递归调用,看不出物理读的数值


    (4)dbms_xplan.display_cursor获取


    步骤1:select * from table( dbms_xplan.display_cursor('&sql_id') ); --该方法是从共享池得到
    注释:
    1.还有1种方法,select * from table( dbms_xplan.display_awr('&sql_id') ); --该方法是从awr性能视图里面获取
    2.如果有多个执行计划,可用以下方法查出:

    select * from table(dbms_xplan.display_cursor('&sql_id',0));
    select * from table(dbms_xplan.display_cursor('&sql_id',1));
    */
    SQL> select * from table(dbms_xplan.display_cursor('5hkd01f03y43d'));
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    SQL_ID 5hkd01f03y43d, child number 0
    -------------------------------------
    select * from test where table_name = 'LOG$'
    Plan hash value: 2408911181
    --------------------------------------------------------------------------------
    | Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
    --------------------------------------------------------------------------------
    | 0 | SELECT STATEMENT | | | | 2 (100)|
    | 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 241 | 2 (0)|
    |* 2 | INDEX RANGE SCAN | IDX_TEST_1 | 1 | | 1 (0)|
    --------------------------------------------------------------------------------
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    2 - access("TABLE_NAME"='LOG$')
    19 rows selected

    注释:如何查看1个sql语句的sql_id,可直接查看v$sql

    优点:1.知道sql_id即可得到执行计划,与explain plan for一样无需执行
                2.可得到真实的执行计划
    缺点:1.没有输出运行的统计相关信息;
                2.无法判断处理了多少行;
                3.无法判断表被访问了多少次;
     


    (5)事件10046 trace跟踪


    步骤1:alter session set events '10046 trace name context forever,level 12'; --开启追踪
    步骤2:执行sql语句;
    步骤3:alter session set events '10046 trace name context off'; --关闭追踪
    步骤4:找到跟踪后产生的文件(开启10046前先用‘ls -lrt’看一下文件,执行结束后再看哪个是多出来的文件即可)
    步骤5:tkprof trc文件 目标文件 sys=no sort=prsela,exeela,fchela --格式化命令

    详细demo可见《附录1:10046追踪demo》

    优点:1.可以看出sql语句对应的等待事件;
                2.如果函数中有sql调用,函数中有包含sql,将会被列出,无处遁形;
                3.可以方便的看处理的行数,产生的逻辑物理读;
                4.可以方便的看解析时间和执行时间;
                5.可以跟踪整个程序包
    缺点:1.步骤繁琐;
                2.无法判断表被访问了多少次;
                3.执行计划中的谓词部分不能清晰的展现出来
     


    (6)awrsqrpt.sql


    步骤1:@?/rdbms/admin/awrsqrpt.sql
    步骤2:选择你要的断点(begin snap和end snap)
    步骤3:输入要查看的sql_id


    详细demo可见《附录2:使用awrsqrpt.sql查看执行计划》


     

     

    展开全文
  • 背景:本渣目前的工作是oracle数据库开发,刚从mysql...本文只讲述oracle执行计划的执行顺序,不涉及执行计划的具体底层活动(即每一步是干了什么,怎么实现的)。 如图,这是一个树形执行计划 文本格式: 那...

    背景:本渣目前的工作是oracle数据库开发,刚从mysql转过来的时候,有极大的不适应!!经过两三个月的过渡,现在终于适应了DQL和存储过程的语法,熬过了这一阶段,才终于算是上了正轨。于是才有心思来研究一下进阶的东西,oracle的执行计划。

    本文只讲述oracle执行计划的执行顺序,不涉及执行计划的具体底层活动(即每一步是干了什么,怎么实现的)。

    如图,这是一个树形执行计划
    在这里插入图片描述
    文本格式:
    在这里插入图片描述
    那么如何来判断执行顺序呢?很简单,首先第一步,在树形执行计划中将所有子节点都合并省略,得到一个最简单的执行计划
    在这里插入图片描述
    按照从右往左、从上往下的顺序,先执行NESTED LOOPS,然后执行BUFFER SORT,参照文本格式的编号,执行顺序为 2 ,7,1,0。
    然后打开2的子节点.
    在这里插入图片描述
    2的子节点里面先执行NESTED LOOPS,再执行TABLE ACCESS BY INDEX ROWID,参照文本格式的编号,即为3,6。
    即可得到3,6,2,7,1,0。
    同理,继续打开3的子节点:
    在这里插入图片描述
    先执行TABLE ACCESS FULL,再执行INDEX RANGE SCAN,即4,5。
    合并得到4,5,3,6,2,7,1,0。
    此时编号为2的节点,其包含的所有子节点的执行顺序已经出来了,可以看到编号7的节点也是有子节点的,该字节点编号为8
    在这里插入图片描述
    于是得到4,5,3,6,2,8,7,1,0。
    是不是很简单咧!

    本文参考:http://blog.itpub.net/30126024/viewspace-2141974/

    展开全文
  • 解读Oracle执行计划(二)

    千次阅读 2018-09-18 21:42:09
    解读Oracle执行计划(二) 一些典型的执行计划:AND-EQUAL(Index merge) AND-EQUAL 这种方式需要查询条件里面包括所有索引列,然后取得每个索引中得到的rowid列表,然后对这些列表做merge join,过滤出相同的...
  • Oracle执行计划之explain plan for

    千次阅读 2018-11-20 20:15:45
    最近一直在跟Oracle打交道,从最初的一脸懵...一:什么是Oracle执行计划? 执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述 &amp;nbsp; &amp;nbsp; 二:怎样查看Oracle执行计划? 因为我...
  • Oracle执行计划中的索引

    千次阅读 2015-05-19 08:40:32
    Oracle执行计划根据索引的类型与where限制条件的不同,有5种类型的索引扫描,分别是:索引唯一扫描(index unique scan),索引范围扫描(index range scan),索引全扫描(index full scan),索引快速扫描(index ...
  • 解读Oracle执行计划

    千次阅读 2013-03-02 14:39:40
    关于生成和显示Oracle执行计划的方法请阅读 http://blog.csdn.net/laoshangxyc/article/details/8629123 下面举例进行解释 SQL> explain plan for 2 select a.name,b.name 3 from t1 a,t2 b 4 where a....
  • ORACLE执行计划中的执行顺序

    千次阅读 2019-01-25 12:21:39
    执行计划的查看规则:(从上往下,从右往左) 先从开头一直连续往右看,直到看到右边并列的地方;对于不并列的,靠右的先执行;如果看到并列,从上往下看,对于并列的部分,靠上的先执行。 参考网站:...
  • Oracle 执行计划详解(预估 + 真实)

    千次阅读 2020-05-19 16:43:35
    文章目录1 概述1.1 思维导图1.2 概念2 执行计划2.1 预估的2.2 真实的3 示例4 备选命令 1 概述 什么是 Oracle执行计划执行计划是一条查询语句...oracle执行计划是很复杂的,一般我们看到的执行计划都是 oracle
  • 如何看懂ORACLE执行计划

    万次阅读 热门讨论 2010-04-22 13:21:00
    如何看懂ORACLE执行计划一、什么是执行计划An explain plan is a representation of the access path that is taken when a query is executed within Oracle.二、如何访问数据At the physical level Oracle reads ...
  • Oracle 执行计划中的buffer sort

    千次阅读 2014-12-26 16:16:33
    Oracle 执行计划中的buffer sort实际上没有排序,只是把数据加载到内存,不扫描多次表。 --制造数据 drop table test purge; drop table test1 purge; create table test as select * from dba_objects where ...
  • 1 启用Autotrace 1.1 以sys用户,运行utlxplan.sql sqlplus / as sysdba SQL> @$ORACLE_HOME/rdbms/...1.2 通过执行plustrce.sql脚本创建plustrace角色 SQL> @$ORACLE_HOME/sqlplus/admin/plustrce.sql 1.3 授权 将
  • Oracle 执行计划优化

    千次阅读 2016-06-13 16:41:53
    Oracle分区执行计划   range分区可用的操作:  分区表,按 n1 ,n2 分区 partition range single:访问单个分区 partition range iterator:访问多个分区 partition range inlist: 分区键中用了in 例如: ...
  • 读懂Oracle执行计划(一)

    万次阅读 2018-11-20 21:11:01
    为什么要有执行计划 ...那Oracle是怎么知道哪个是小表哪个是大表呢,Oracle执行计划准吗? 这个就涉及到Oracle收集统计信息。比如Oracle 11g1默认启动了统计信息收集的任务(也可以关闭自动统计新收集任务...
  • Navicat中Oracle执行计划

    千次阅读 2018-11-06 10:35:32
    explain plan for 要执行的语句; select * from table(dbms_xplan.display);
  • ORACLE执行计划的步骤和顺序

    千次阅读 2010-08-18 13:04:00
    阅读oracle执行计划的方法: 先从最开头一直往右看,直到看到最右边的并列的地方,对于不并列的,靠右的先执行:对于并列的,靠上的先执行。  即并列的缩进块,从上往下执行,非并列的缩进块,从下往上执行。 ...
  • 查看Oracle执行计划的几种方法

    万次阅读 2010-04-20 14:08:00
    查看Oracle执行计划的几种方法一、通过PL/SQL Dev工具 1、直接File->New->Explain Plan Window,在窗口中执行sql可以查看计划结果。其中,Cost表示cpu的消耗,单位为n%,Cardinality表示执行的行数,等价Rows。 2...
  • 查看Oracle执行计划的几种常用方法-系列1

    万次阅读 多人点赞 2014-08-30 22:08:15
    SQL的执行计划实际代表了目标SQL在Oracle数据库内部的具体执行步骤,作为调优,只有知道了优化器选择的执行计划是否为当前情形下最优的执行计划,才能够知道下一步往什么方向。 执行计划的定义:执行目标SQL的...
  • Oracle执行计划的6种方法

    千次阅读 2017-12-31 00:08:01
    获取执行计划的6种方法(详细步骤已经在每个例子的开头注释部分说明了):  1. explain plan for获取;   2. set autotrace on ;   3. statistics_level=all;  4. 通过dbms_xplan.display_cursor...
  • 消耗在准备利用Oracle执行计划机制提高查询性能新的SQL语句的时间是Oracle SQL语句执行时间的最重要的组成部分。但是通过理解Oracle内部产生执行计划的机制,你能够控制Oracle花费在评估连接顺序的时间数量,并且能...
  •  在查看执行计划的信息中,经常会看到两个谓词filter和access,它们的区别是什么,理解了这个两个词对我们解读Oracle执行计划信息会有所帮助。  简单地说,执行计划如果显示是access,就表示这个谓词条件的值...
  • 所遵循的是oracle内部预定的一些规则. b) CBO(cost-based optimizer)方式:看语句的执行代价(cost),这里的代价主要指cpu和内存。 优化器在判断是否用这种方式时,主要参照的是表及索引的统计信息。
  • http://blog.51cto.com/xiao1ang/1900950
  • oracle 执行计划(Explain Plan) 说明

    千次阅读 2015-05-29 22:50:47
    如果要分析某条SQL的性能问题,通常我们要先看SQL的执行计划,看看SQL的每一步执行是否存在问题。 如果一条SQL平时执行的好好的,却有一天突然性能很差,如果排除了系统资源和阻塞的原因,那么基本可以断定是执行...
  • Oracle 执行计划(2)-基数 cardinality 执行计划的cardinality列。基数是说从数据表,结果集或者索引返回多少行数据。 基数=表行数据*选择率。所以讲基数重点是讲选择率,选择率的计算! 版本10G 默认 表空间...
  • oracle执行计划中cost cpu

    万次阅读 2014-05-23 23:31:44
    Oracle 10g中,Oracle 把CPU的cost也统计在执行计划中去了, 这和以前的8i,9i(9i其实已经开始了)有很大的不同。 所以用一个公式来表示cost,可以简单的写成 Cost = I/O cost + CPU cost 我虚拟机的...
  • Oracle 执行计划(Explain Plan) 说明

    万次阅读 热门讨论 2010-08-20 17:23:00
    如果要分析某条SQL的性能问题,通常我们要先看SQL的执行计划,看看SQL的每一步执行是否存在问题。如果一条SQL平时执行的好好的,却有一天突然性能很差,如果排除了系统资源和阻塞的原因,那么基本可以断定是执行计划...
  • Oracle执行计划不走索引的原因总结

    万次阅读 2016-08-03 14:00:35
    Oracle数据库操作中,为什么有时一个表的某个字段明明有索引,当观察一些语的执行计划确不走索引呢?如何解决呢?本文我们主要就介绍这部分内容,接下来就让我们一起来了解一下。  不走索引大体有以下几个原因...
  • oracle 执行计划(explain plan)说明

    千次阅读 2011-10-26 21:02:27
    基于oracle的应用系统很多性能问题,是由应用系统sql性能低劣引起的,所以,sql的性能优化很重要,分析与优化sql的性能我们一般通过查看该sql的执行计划,本文就如何看懂执行计划,以及如何通过分析执行计划对sql...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 606,584
精华内容 242,633
关键字:

oracle执行计划