




已阅读5页,还剩17页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Oracle9i 优化器介绍By DavisE-Mail:Blog:选择合适的优化器目标默认情况下,CBO 以最佳吞吐量为目标,这意味着 Oracle 使用尽可能少的资源去处理被语句访问到的所有行;当然 CBO 也可以用最快的响应速度来优化 SQL,这意味着 Oracle用尽可能少的资源去处理被语句访问到的第一行或前面少数行,当然这种情况对于整个语句来说可能消耗更多的资源。优化器产生的执行计划会因“优化器目标”的不同而不同。如果以最佳吞吐量为目标,结果更倾向于使用全表扫描而不是索引扫描,或者使用排序合并连接而不是嵌套循环连接;如果以最快的响应速度为目标,其结果则通常倾向于使用索引扫描和嵌套循环连接。例如,假使你有一个语句既能运行于嵌套循环连接又能运行于排序合并连接,排序合并连接能够较快的返回全部查询结果,而嵌套循环能快速的返回第一行或前面少数行结果。如果你是以提高吞吐量为优化器目标,优化器就会倾向于选择排序合并连接;如果你的优化器目标是提高响应速度,则优化器倾向于选择嵌套循环连接。选择优化器目标要以你的应用为基础,一般规则是:1、 对于批处理应用,以最佳吞吐量为优化目标为好。例如 Oracle 报表应用程序。2、 对于交互式应用,以最快响应速度为优化目标为好。例如 SQLPLUS 的查询。影响优化器优化目标的因素主要有:1、 OPTIMIZER_MODE 初始化参数。2、 数据字典中的 CBO 统计数据。3、 用来改变 CBO 优化目标的 Hints。OPTIMIZER_MODE 初始化参数这个初始化参数用来规定实例的默认优化方法。其值列表及说明如下:ValueCHOOSEALL_ROWSDescription此为缺省值。优化器既可以使用基于成本的优化方法(CBO),也可以使用基于规则的优化方法(RBO),其决定于是否有可用的统计信息。1、 如果在被访问的表中,至少有一个表在数据字典中有可用的统计信息存在,则优化器使用基于成本的方法。2、 如果在被访问的表中,只有部分表在数据字典中有可用的统计信息,优化器仍然会使用基于成本的方法,但是优化器必须为无统计信息的表利用一些内部信息去尝试其他的统计,比如分配给这些表的数据块的数量等,这可能会导致产生不理想的执行计划。3、 如果在被访问的表中,没有一个表在数据字典中有统计信息,则优化器使用基于规则的方法。不论是否有统计信息存在,优化器都使用基于成本的方法,并以最佳吞1吐量为优化目标。FIRST_ROWS_n 不论是否有统计信息存在,优化器都使用基于成本的方法,并以最快的速度返回前 n 行数据集,n 可以是 1,10,100,1000。FIRST_ROWSRULE优化器使用成本与试探法混合的方式,去寻找一个可以最快返回前面少数行的执行计划。注:CBO 使用试探法产生的执行计划,其成本可能会比不使用试探法要大。FIRST_ROWS 可用于向后兼容和计划稳定性。不论是否有统计信息存在,优化器都会使用基于规则的方法。你可以在 SESSION 中改变 CBO 优化目标:ALTER SESSION SET OPTIMIZER_MODE。例如:1、在初始化参数文件中加入如下语句,可以在实例级改变 CBO 优化目标:OPTIMIZER_MODE=FIRST_ROWS_12、下面的语句可以改变当前 SESSION 的 CBO 优化目标:ALTER SESSION SET OPTIMIZER_MODE=FIRST_ROWS_1可以改变 CBO 优化目标的 Hints使用如下 Hints 可以单独为具体的 SQL 指定 CBO 优化目标,SQL 语句中 Hints 能够覆盖 OPTIMIZER_MODE 初始化参数。lFIRST_ROWS(n),n 为任意正整数。lFIRST_ROWSlALL_ROWSlCHOOSElRULE数据字典中的 CBO 统计信息CBO使用的统计信息存放于数据字典中,你可以使用 DBMS_STATS 包或 ANALYZE语句以精确的方式或估算的方式来统计对象的物理存储特征和数据分布情况。注意:Oracle公 司 建 议 使 用DBMS_STATS包 来 代 替ANALYZE语 句 收 集 统 计 信 息 。DBMS_STATS 包可以并行的收集统计信息,可以为分区对象收集全局统计信息,以及使用其他方式优化收集操作。但是,收集和基于成本优化器无关的信息必须用 ANALYZE 而不是 DBMS_STATS,比如:l使用 VALIDATE 或 LIST CHAINED ROWS子句。l收集 freelist 块的信息。CBO 如何对 SQL 做最快响应的优化2OPTIMIZER_MODE 被设置成 FIRST_ROWS_n、FIRST_ROWSS,或者 SQL 语句中使用了 FIRST_ROWS(n)、FIRST_ROWS 提示,CBO 都会对 SQL 做最快响应的优化。这非常适用于联机用户,像通过 Oracle Forms 或 Web 访问的用户。联机用户的特点是只对前面少数行感兴趣,很少看整个查询的结果,特别是在查询结果巨大的情况下。对于这样的用户,优化 SQL 使前面少数行尽可能快速的返回是有意义的,即使产生整个查询结果的时间并不理想。CBO 在做这种优化时,会产生一个处理第一行或前面少数行消耗成本最低的执行计划。CBO有两种用来产生最快响应速度的方法,一个是旧方法一个是新方法。旧的方法就是用FIRST_ROWS 提示或初始化参数,这种方法 CBO 会使用成本和规则混合的方式来产生一个计划。Oracle 保留这种方法是为了向后兼容。新方法 FIRST_ROWS_n 或 FIRST_ROWS(n)提示,是完全基于成本的。如果 n 值较小,CBO 倾向于产生一个包含嵌套循环连接和索引查询的执行计划;如果 n 值较大,则 CBO 倾向于产生一个包含散列连接和全表扫描的执行计划。理解基于成本的优化器CBO 根据可用的访问路径和表、索引等对象的统计信息来确定当前 SQL 的哪个执行计划是最高效的或成本最低的;同时 CBO 也会考虑 Hints 的建议。CBO 执行下列步骤:1、 优化器根据可用的访问路径和 Hints 为 SQL 语句产生一组潜在的执行计划。2、 优化器根据数据字典的统计信息评估每个计划的成本。成本就是一个评估值,它与SQL语句按照某个计划执行所消耗的计算机资源是成正比的。优化器基于对计算机资源(I/O、CPU、内存)的评估,计算访问路径和连接顺序的成本。3、 优化器对比执行计划的成本,从而选择一个成本最低的执行计划。CBO 包含下列组件:l查询变换器(Query Transformer)l评估器(Estimator)l计划生成器(Plan Generator)如下图所示:3查询变换器(基于成本的优化器组件)被解析器解析过的查询语句进入查询变换器,表现出来的是一组查询块(query block),这些查询块之间是相互关联的或者是嵌套的,查询的形式决定这些查询块相互之间如何被关联。查询变换器的主要目的就是决定改变查询的形式是否有利于产生一个好的执行计划。查询变换器使用四种不同的查询变换技术:l视图合并(View Merging)l谓词推进(Predicate Pushing)l非嵌套子查询(Subquery Unnesting)l物化视图的查询重写(Query Rewrite with Materialized Views)最终应用于查询的也可以是以上四种变换技术的任意组合。视图合并查询中的每个视图都会被解析器扩展到一个独立的查询块中,这个查询块本质上是用来描述视图定义的,是视图的结果。优化器的一个任务就是去分析这个独立视图查询块(viewquery block)并产生一个视图子计划(subplan),然后优化器在产生整个查询执行计划的同时使用视图子计划来处理剩余的查询部分。由于视图是被独立在整个查询之外被优化的,因此这种技术常常会导致一个不良执行计划的产生。查询变换器通过将视图查询块合并到查询块中从而消除这种不良执行计划。绝大多数类型的视图是可以被合并的。在一个视图被合并后,它原有的视图查询块被包含到查询块中,也就是说视图查询块不存在了,因此也不再需要产生一个子计划。谓词推进4对于那些不能合并的视图,查询变换器能够将相关的谓词从查询块中推进到视图查询块中。由于被推进的谓词能够用来访问索引或者用于过滤,这个技术通常可以改进那些不能被合并的视图子计划。非嵌套的子查询和视图一样,子查询也是用一个独立的查询块来代表的。子查询是被嵌套在主查询或其他子查询之中的,计划产生器在找到一个成本最低的执行计划之前被迫要试验所有可能的计划。由嵌套子查询产生的限制可以在转换为非嵌套的子查询和连接之后消除,经由查询转换器过滤之后绝大多数的子查询都会被转换为非嵌套的,然后这些非嵌套的子查询产生独立的子计划,这些子计划按照一种高效的方式进行排列,从而提高了整个查询计划的执行速度。物化视图的查询重写物化视图就是把一个查询的结果事先固化存储在一个表里,当发现和物化视图一致的查询语句就将相应的项用物化视图来重写。由于绝大多数的查询结果都事先计算好了,因此这种技术可以极大的提高查询速度。查询转换器负责查找和用户查询相关的所有物化视图,用其中的一个或多个来重写查询。利用物化视图来重写查询也是基于成本的,如果不使用物化视图的成本更低一些,则不会去使用物化视图。评估器评估器会产生下列三个度量值:l选择性(Selectivity)l基数(Cardinality)l成本(Cost)这些值是相互关联的,一个值由其他值导出,评估器的最终目标是评估计划的总体成本。如果有统计信息可用,评估器使用统计信息来计算这些值,统计信息可以提高其精确度。选择性这里的第一个度量值选择性,表示所选择的行与行集的比值。所谓行集可以是表、视图,或者是一个连接或 GROUP BY 操作的中间结果。选择性与查询中的谓词有关,比如last_name=Smith,或者一个联合谓词 last_name=Smith and job_type=Clerk。一个谓词充当着一个过滤器的角色,在行集中过滤了一定量的行,谓词的选择性是一个比值,它表示一个行集经过谓词的过滤后剩下的行占原有行集的比例。其值在 0.0 和 1.0 之间,0.0 表示在行集中没有行被选择;1.0 表示行集中的所有行都被选择了。如果没有可用的统计信息,评估器为选择性赋予一个内部的缺省值,这个内部缺省值随着谓词的不同而不同。例如:等式谓词(last_name=Smith)的内部缺省值低于范围谓词(last_nameSmith),评估器会假定等式谓词返回的行数小于范围谓词。当存在可用的统计信息,评估器将使用统计信息来估算选择性。例如:对于一个等式谓词 ( last_name=Smith ), 选 择 性的 值是distinct last_name的 倒 数 即 :( 1/count(distinctlast_name))。但是如果在last_name 字段上存在直方图(histogram),则选择性值为:count5(last_name)where last_name=Smith / count(last_name)where last_name is not null。可见在数据倾斜的字段上应用直方图能够帮助 CBO 进行准确的选择性评估。基数基数就是行集中行的数量。基数分为:l基础基数(Base cardinality):就是基表中的行数。基础基数在表分析期间获得。如果表没有可用的统计信息,则评估器利用表中区(extents)的数量来估算基础基数。l有效基数(Effective cardinality):就是从基表中选择的行数。有效基数与具体的谓词和字段有关。有效基数是根据基础基数和作用于该表的所有谓词的选择性得出的,如果没有谓词作用于该表,则有效基数就等于基础基数。l连接基数(Join cardinality):就是两个行集在连接之后产生的行数。连接就是由两个行集产生的笛卡尔积,再由连接谓词过滤结果。因此,连接基数是两个行集基数与连接谓词选择性的乘积。lDistinct 基数(Distinct cardinality):就是一个行集的字段 distinct 之后的行数。一个行集的 distinct 基数是基于字段中的数据的。例如:一个拥有 100 行的行集,如果一个字段 distinct 之后还剩下 20 行,则 distinct 基数就为 20。lGroup 基数(Group cardinality):就是一个行集在应用 GROUP BY 之后产生行的数量。Group 基数依赖于每个组中字段的 distinct 基数和行集的行数。GROUP 基数例子:假如对一个有 100 行的行集 group by colx,colx 字段的 distinct 基数是 30,则 Group 基数为 30。但是如果 group by colx,coly 呢?coly 字段的 distinct 基数是 60,这种情况下 Group基数大于 max(colx distinct 基数,coly distinct 基数),而小于 min(colx distinct 基数*coly distinct基数,行集的行数),用公式表示出来如下:group cardinality lies between max ( dist. card. colx , dist. card. coly ) and min ( (dist. card. colx * dist. card. coly) , num rows in row set ) 对于上面的例子 Group 基数大于 max(30,60)而小于 min(30*60,100),也就是 Group基数位于 60 和 100 之间。成本成本是用来描述工作单元或资源使用的。CBO是用磁盘I/O、CPU 和内存的使用情况来作为工作单元的,因此 CBO 使用的成本可以描述为,在一次操作的执行过程中所用的磁盘 I/O 数量以及 CPU 和内存的总使用量。这里的操作可以是扫描一张表、通过索引访问表、连接两个表、或者一个行集的排序。一个查询计划的成本就是运行这个查询并产生结果的同时需要的工作单元的数量。访问路径(access path)决定着在基表中获得数据所需要的工作单元数量。访问路径可以是表扫描(table scan)、快速全索引扫描(fast full index scan)、索引扫描(index scan)等。在表扫描或快速全索引扫描期间,多个块可以在一次 I/O 中获得,因此表扫描或快速全索引扫描的成本依赖于被扫描的块数和多块读取的数量。索引扫描的成本依赖于B 树的深度、被扫描的索引页块数量、和用 ROWID 获取的行数,使用 ROWID 获取行的成本倚赖于索引6聚集因子(clustering factor)。尽管聚集因子是索引的一个属性,它实际也关系到表数据块中被索引的字段值。一较低的聚集因子表明行被集中在表的少数块里,相反一个较高的聚集因子表明行被随机分散到表的数据块中。因此,聚集因子过高意味着通过范围扫描用 ROWID 获取行成本会较高,因为需要访问表中过多的块才能返回数据。聚集因子对成本的影响假设环境如下:l一个表有 9 行数据。l在 col1 上有一个非唯一索引ldistinct col1 值是 A、B、Cl这个表占据三个 Oracle 块第一种情况:索引聚集因子低,如下图: Block 1 Block 2 Block 3 - - - A A A B B B C C C 索引字段相同的值都在同一个物理块中,这种情况下做范围扫描返回 col1=A 的所有的行成本就很低,因为只需要在表中读取一个块就可以返回数据。第二种情况:索引聚集因子高,如下图: Block 1 Block 2 Block 3 - - - A B C A B C A B C索引字段相同的值被分散存储到表中的块,这时要得到 col1=A 的行则要读取三个块。联合单独访问两个表的成本就是连接的成本,在一个连接中分为内行集和外行集。l嵌套循环连接(nested loop join):对于外行集中的每一行都要在内行集寻找全部与它匹配的行,然后连接。因此,在嵌套循环连接中外行集有多少行,内行集就被访问多少次。成本计算公式如下:cost = outer access cost + (inner access cost * outer cardinality)l排序合并连接(sort merge join):如果两个行集的连接键是无序的,则进行排序。成本计算公式如下:cost = outer access cost + inner access cost + sort costs (if sort is used)l散列连接(hash join):内部行集被散列到内存中,并用连接键建立一个散列表,然后探测外部行集并连接与之匹配的行。如果内部行集非常大,则只会把一部分散列到内存中,这叫做一个散列分区。此时,内存中的散列分区探测外部行集并连接所有匹配的行,重复这个过程直到用完内部行集的所有分区。成本计算公式如下:cost = (outer access cost * num of hash partitions) + inner access cost计划生成器7由于不同的访问路径、连接方式和连接顺序可以任意组合,以不同的方式访问和处理数据,但可以产生同样的结果,因此一个 SQL 可能存在大量不同的计划。计划生成器的主要作用正是为查询试验出所有这些可能存在的计划,并选择一个其中成本最低的。连接顺序就是不同的连接项(如,表)以一定的顺序被访问和连接在一起。例如:有一个连接按照 t1、t2、t3 的顺序,则 t1 是第一个被访问的,然后是 t2,访问 t2 的同时与 t1 做连接并产生连接后的结果,最后 t3 被访问,t3 的数据与 t1 和 t2 产生的中间结果做连接。在建立一个查询的计划之前要先为每个被嵌套的子查询和未合并的视图建立子计划,每个嵌套的子查询和未合并的视图都是独立的查询块,这些查询块以自底向上的顺序进行优化,也就是最里层的查询块最先优化并产生子计划,最外层的查询块最后优化。计划生成器通过试验不同的访问路径、连接方式和连接顺序去探测各种计划,对于一个查询来说可能存在的计划与 FROM 字句后面的连接项是成比例的,并以指数增长。然而实际上计划生成器很少会试验所有的可能存在的计划,如果它发现当前计划的成本已经很低了,它将停止试验,相反当前计划的成本如果很高它将继续试验其他计划,因此如果计划生成器一开始就能够找到一个成本较低的计划则会大量减少时间,计划生成器通常按照连接项有效基数由小到大的顺序排列初使连接,。理解执行计划Oracle 用来运行一个语句的步骤就叫做执行计划(execution plan),执行计划包含了语句所涉及的每个表的访问路径和连接顺序。执行计划概述使用 EXPLAIN PLAN 语句可以查看优化器所选择的执行计划,下面看一个例子:1、创建 PLAN_TABLE,用来存放执行计划的描述信息:CONNECT HR/your_password$ORACLE_HOME/RDBMS/ADMIN/UTLXPLAN.SQL Table created.当然你也可以改变 PLAN_TABLE 的名字。注意:Oracle 公司建议你在做完数据库版本升级之后删除 PLAN_TABLE 然后再重建,因为字段可能会有所变化,这可能会导致脚本失效或 TKPROF 失效。当然你也可以改变 PLAN_TABLE 的名字。2、运行执行计划:8EXPLAIN PLAN FORSELECT e.employee_id, j.job_title, e.salary, d.department_name FROM employees e, jobs j, departments d WHERE e.employee_id 103 AND e.job_id = j.job_id AND e.department_id = d.department_id;用下面的语句可以指定 PLAN_TABLE 的名字:EXPLAIN PLAN INTO my_plan_table FORYOUR_SQL;3、显示执行计划信息:这里可以用以下两个脚本UTLXPLS.SQL 显示计划表信息,以串行的方式处理。UTLXPLP.SQL 显示计划表信息,以并行的方式处理。$ORACLE_HOME/rdbms/utlxplp.sql;-| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|-| 0 | SELECT STATEMENT | | 3 | 189 | 10 (10)| 1 | NESTED LOOPS | | 3 | 189 | 10 (10)| 2 | NESTED LOOPS | | 3 | 141 | 7 (15)|* 3 | TABLE ACCESS FULL | EMPLOYEES | 3 | 60 | 4 (25)| 4 | TABLE ACCESS BY INDEX ROWID| JOBS | 19 | 513 | 2 (50)|* 5 | INDEX UNIQUE SCAN | JOB_ID_PK | 1 | | | 6 | TABLE ACCESS BY INDEX ROWID | DEPARTMENTS | 27 | 432 | 2 (50)|* 7 | INDEX UNIQUE SCAN | DEPT_ID_PK | 1 | | |-Predicate Information (identified by operation id):- 3 - filter(E.EMPLOYEE_ID310后面的 cost 说明该 SQL 是基于成本优化的,如果没有 cost 则是基于规则的。通过这个例子可以知道学会看执行计划也不是什么难事,关键是要理解执行计划,学会如何优化执行计划,下面将继续讨论。理解 CBO 访问路径访问路径就是从数据库中检索数据的方式。通常来说,检索一个表中少量的数据行应该使用索引访问,但是检索大量数据时全表扫描可能优于索引。全表扫描(Full Table Scans)全表扫描将读取 HWM 之下的所有数据块,访问表中的所有行,每一行都要经 WHERE子句判断是否满足检索条件。当Oracle 执行全表扫描时会按顺序读取每个块且只读一次,因 此 如 果 能 够 一 次 读 取 多 个 数 据 块 , 可 以 提 高 扫 描 效 率 , 初 始 化 参 数DB_FILE_MULTIBLOCK_READ_COUNT 用来设置在一次 I/O 中可以读取数据块的最大数量。优化器何时会使用全表扫描在以下情况中优化器会使用全表扫描:1、无可用索引如下面例子:SELECT last_name, first_name FROM employees WHERE UPPER(last_name)=TOM11last_name字段有索引,但在查询中使用了函数,因此该查询不会使用索引。如果想让这 个查 询走 索引 ,则 需要 建立 函数 索引create index ind_upper_lastname on last_name(upper(last_name)。特别要注意的是隐式转换,比如 colx 字段是 varchar2型但存放数字:where colx=123456,这时会发生隐式转换 TO_NUMBER(colx),此时 colx 上的索引也会失效。2、大量数据如果优化器认为查询将会访问表中绝大多数的数据块,此时就算索引是可用的也会使用全表扫描。3、小表如果一个表 HWM 之下的数据块比 DB_FILE_MULTIBLOCK_READ_COUNT 要少,只需要一次 I/O 就能扫完,则使用全表扫描要比使用索引的成本低,此时会使用全表扫描。如果有这样小表访问频率又高,通常把它固定在内存中为好alter table table_namestorage(buffer_pool keep)。4、并行如果在表一级设置了较高的并行度,如 alter table table_name parallel(degree 10),通常会使 CBO 错误的选择全表扫描。通常不建议在表级的设置并行。并行查询通常可以提高全表扫描的性能,建议在语句级用HINTS来实现并行,如/*+full(table_name) parallel(table_name degree)*/。5、全表扫描 hints如果想强制优化器使用全表扫描可以用提示 FULL。I/O 是针对数据块的而不是行Oracle 的 I/O 是针对数据块的,因此被访问的数据块所占的百分比将影响 CBO 是否选择全表扫描。通常一个数据块中存储着多条记录,被请求的记录要么聚集在少数几个块中,要么分散在大量的数据块中。HWM(High Water Mark)HWM 是全表扫描范围的标记,每个全表扫描都要读到 HWM 位置。当表 analyze 之后可以在 DBA_TABLES.BLOCKS 查到 HWM,当表被 drop、truncate 或者 move 之后,HWM将会被重置。需要注意的是,当一个表被大量删除记录之后,HWM 下面的大量数据块是空的,此时若对此表进行全表扫描,Oracle 仍然会读到 HWM 位置,会对全表扫描的性能产生极坏的影响。Rowid 扫描Rowid 就是一个记录在数据块中的位置,由于指定了记录在数据库中的精确位置,因此rowid 是检索单条记录的最快方式。如果通过rowid来访问表,Oracle首先需要获得被检索记录的rowid,Oracle可以在WHERE 子句中得到 rowid,但更多的是通过索引扫描来获得,然后 Oracle 基于 rowid 来定12位被检索的每条记录。优化器何时使用 Rowid并不是每个索引扫描都伴随着 rowid 的访问,如果索引中包含了被访问的所有字段,则不再需要通过 rowid 来访问表。注意:Rowid 是 Oracle表示数据存储的内部方法,它可能会由于版本的改变而改变。不推荐通过在 WHERE 中指定 rowid 来访问数据,因为行迁移和行链接会导致 rowid 变化,exp/imp 也会使 rowid 变化。索引扫描索引不仅包含被索引字段的值,还包含表中行的位置标识 rowid,如果语句只检索索引字段,Oracle 直接从索引中读取该值而不去访问表,如果语句通过索引检索其他字段值,则Oracle 通过 rowid 访问表中记录。索引扫描类型:l索引唯一扫描(Index Unique Scans)l索引范围扫描(Index Range Scans)l索引降序范围扫描(Index Range Scans Descending)l索引跳跃扫描(Index Skip Scans)l全索引扫描(Full Scans)l快速全索引扫描(Fast Full Index Scans)l索引连接(Index Joins)l位图连接(Bitmap Joins)1、索引唯一扫描这种扫描通常发生在对一个主键字段或含有唯一约束的字段指定相等条件时,只有单行记录被访问。2、索引范围扫描索引范围扫描是检索数据的常用方式,返回的数据返照索引字段升序排列,字段值相同的则按照 rowid 升序排列。如果在语句中指定了 order by 字句,而且排序字段是索引字段时Oracle 将忽略 order by 子句。例如:SQL select * from t; COLX COLY- - 1 3 1 2 1 113 1 0SQL create index ind_t on t(coly);SQL set autotrace onSQL select * from t where coly0; COLX COLY- - 1 1 1 2 1 3Execution Plan- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (BY INDEX ROWID) OF T 2 1 INDEX (RANGE SCAN) OF IND_T (NON-UNIQUE)没有使用 order by 结果集已经是按 coly 升序排列的。SQL set autotrace traceonlySQL select * from t where coly0 order by coly;Execution Plan- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (BY INDEX ROWID) OF T 2 1 INDEX (RANGE SCAN) OF IND_T (NON-UNIQUE)可以看到执行计划中无 SORT步骤,说明 Oracle 忽略了 order by 子句。3、索引降序范围扫描如果在 order by 中指定了索引是降序排列的,或者使用了 index_desc 提示,Oracle 可能会使用索引降序范围扫描。例如:SQL sel
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 物业管理服务协议细则
- 公文写作的重要性与2025年试题及答案
- 通信行业智能化通信设备维护与升级方案
- 车位租赁共享协议
- 行政管理学考试思维导图及试题及答案
- 自考行政管理知识总结试题及答案
- 行政管理学知识更新试题及答案
- 现代管理学思维模式的试题及答案
- 2025企业长期借款合同模板
- 2025年挖掘机租赁合同
- RULES OF ORIGIN 原产地规则
- 国内旅游出团通知书(新版)
- LETTEROFINTENTION意向书范本
- 国内各航空公司差异化服务
- 《山东省自然科学基金资助项目年度进展报告》
- 发展与教育心理学个别差异
- 2022年重庆市建筑安全员A证考试近年真题汇总(含答案解析)
- 沸腾炉的设计
- 太仓德资企业
- 电网有限公司电网建设项目档案管理办法
- 简易离职申请
评论
0/150
提交评论