收藏 分享(赏)

数据库索引原理.pdf

上传人:精品资料 文档编号:10597002 上传时间:2019-12-04 格式:PDF 页数:19 大小:152.55KB
下载 相关 举报
数据库索引原理.pdf_第1页
第1页 / 共19页
数据库索引原理.pdf_第2页
第2页 / 共19页
数据库索引原理.pdf_第3页
第3页 / 共19页
数据库索引原理.pdf_第4页
第4页 / 共19页
数据库索引原理.pdf_第5页
第5页 / 共19页
点击查看更多>>
资源描述

1、索引概述 概述 索引在各种关系型数据库系统中都是举足轻重的组成部分, 其对于提高检索 数据的速度起至关重要的作用。在Oracle中,索引基本分为以下几种:B*Tree 索引,反向索引,降序索引,位图索引,函数索引,interMedia全文索引等。 本文主要就前6种索引进行分析。 首先给出各种索引的简要解释: b*tree index:几乎所有的关系型数据库中都有b*tree类型索引,也是被 最多使用的。其树结构与二叉树比较类似,根据rid快速定位所访问的行。 反向索引:反转了b*tree索引码中的字节,是索引条目分配更均匀,多用 于并行服务器环境下,用于减少索引叶的竞争。 降序索引:8i中新出

2、现的索引类型,针对逆向排序的查询。 位图索引:使用位图来管理与数据行的对应关系,多用于OLAP系统。 函数索引:这种索引中保存了数据列基于function返回的值,在select * from table where function(column)=value这种类型的语句中起作用。 ORACLE索引的分类:按照索引的基本分类可以分为b*tree索引,反向索引,降 序索引,位图索引,函数索引, interMedia全文索引。 Oracle初学者入门指南-索引是干什么用的? 关于索引是什么的最简单的比喻是,索引好像是表数据前面的目录表,里面 记录着各个章节的页码。 通过目录的页码我们可以快速的

3、定位一个内容,同样通过索引记录的rowid 我们可以快速的定位一条数据。 如同目录很难针对书中每个字词一样,索引也很难针对所有字段。 我们通常索引最能代表章节,记录属性的内容。 索引并非总能带来性能提升,但是通常情况下,索引能加快访问,所以建表 的时候,你一定要知道还有索引这样一类对象。 下面这个案例是我们绝对不应该和不想看到的。 今天一个部门报数据库巨慢无比,上去看了一下,抓到如下的SQL: SQL select sql_text 2 from v$sqltext a 3 where a.hash_value = ( 4 select sql_hash_value from v$sessio

4、n b 5 where b.sid= INDEX_NAME - 没有索引意味着,即使为了获取这一条记录,Oracle 也必须对 5.28G 的一 个表进行全表扫描,如果不慢那就怪了: SQL col segment_name for a20 SQL select segment_name,bytes/1024/1024/1024 from dba_segments where segment_name=upper(i_cm_power); SEGMENT_NAME BYTES/1024/1024/1024 - - I_CM_POWER 5.28173828125 创建一个索引再说: SQL c

5、reate index idx_i_cm_power_sjh on i_cm_power(sjh); Index created. Elapsed: 00:20:50.73 SQL col segment_name for a20 SQL select segment_name,bytes/1024/1024 MB 2 from dba_segments where segment_name=upper(idx_i_cm_power_sjh); SEGMENT_NAME MB - - IDX_I_CM_POWER_SJH 1360 SQL 无疑这个索引对于这样的简单查询是大有益处的: SQL

6、select * from i_cm_power t WHERE T.SJH=13911xxxxx6; Elapsed: 00:00:00.07 Execution Plan - 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (BY INDEX ROWID) OF I_CM_POWER 2 1 INDEX (RANGE SCAN) OF IDX_I_CM_POWER_SJH (NON-UNIQUE) Statistics - 0 recursive calls 0 db block gets 6 consistent gets 0 p

7、hysical reads 0 redo size 1022 bytes sent via SQL*Net to client 503 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 2 rows processed 然而在实际中,你需要考虑更多的因素。 增加索引会占用更多的存储空间;索引的维护会增加数据库的负担,如果有 海量的数据加载,可能会极大影响性能. 所以事实可能总是比你想象的更复杂,你只有知道的更多. ORACLE索引与

8、高性能SQL介绍 什么是索引 索引是建立在表的一列或多个列上的辅助对象,目的是加快访问表中的数 据; Oracle存储索引的数据结构是B*树,位图索引也是如此,只不过是叶子节 点不同B*数索引; 索引由根节点、分支节点和叶子节点组成,上级索引块包含下级索引块的索 引数据,叶节点包含索引数据和确定行实际位置的rowid。 使用索引的目的 加快查询速度 减少I/O操作 消除磁盘排序 何时使用索引 查询返回的记录数 排序表40% 非排序表 7% 表的碎片较多(频繁增加、删除) 索引的种类 非唯一索引(最常用) 唯一索引 位图索引 局部有前缀分区索引 局部无前缀分区索引 全局有前缀分区索引 散列分区索

9、引 基于函数的索引 管理索引的准则 在表中插入数据后创建索引 。在用SQL*Loader或import工具插入或装载数据后,建立索引比较有效; 索引正确的表和列 。经常检索排序大表中40%或非排序表7%的行,建议建索引; 。为了改善多表关联,索引列用于联结; 。列中的值相对比较唯一; 。取值范围(大:B*树索引,小:位图索引); 。Date型列一般适合基于函数的索引; 。列中有许多空值,不适合建立索引 为性能而安排索引列 。经常一起使用多个字段检索记录,组合索引比单索引更有效; 。把最常用的列放在最前面,例:dx_groupid_serv_id(groupid,serv_id), 在where

10、条件中使用groupid或groupid,serv_id,查询将使用索引,若仅用到 serv_id字段,则索引无效; 。合并/拆分不必要的索引。 限制每个表索引的数量 。一个表可以有几百个索引(你会这样做吗?),但是对于频繁插入和更新 表,索引越多系统CPU,I/O负担就越重; 。建议每张表不超过5个索引。 删除不再需要的索引 。索引无效,集中表现在该使用基于函数的索引或位图索引,而使用了B* 树索引; 。应用中的查询不使用索引; 。重建索引之前必须先删除索引,若用alter index rebuild重建索引, 则不必删除索引。 索引数据块空间使用 。创建索引时指定表空间,特别是在建立主键时

11、,应明确指定表空间; 。合理设定pctfress,注意:不能给索引指定pctused; 。估计索引的大小和合理地设置存储参数,默认为表空间大小,或initial 与next设置成一样大。 考虑并行创建索引 。对大表可以采用并行创建索引,在并行创建索引时,存储参数被每个查询 服务器进程分别使用,例如:initial为1M,并行度为8,则创建索引期间至少 要消耗8M空间; 考虑用nologging创建索引 。对大表创建索引可以使用nologging来减少重做日志; 。节省重做日志文件的空间; 。缩短创建索引的时间; 。改善了并行创建大索引时的性能。 怎样建立最佳索引 明确地创建索引 create

12、index index_name on table_name(field_name) tablespace tablespace_name pctfree 5 initrans 2 maxtrans 255 storage ( minextents 1 maxextents 16382 pctincrease 0 ); 创建基于函数的索引 。常用与UPPER、LOWER、TO_CHAR(date)等函数分类上,例: create index idx_func on emp (UPPER(ename) tablespace tablespace_name; 创建位图索引 。对基数较小,且基数相对

13、稳定的列建立索引时,首先应该考虑位图索引, 例: create bitmap index idx_bitm on class (classno) tablespace tablespace_name; 明确地创建唯一索引 。可以用create unique index语句来创建唯一索引,例: create unique index dept_unique_idx on dept(dept_no) tablespace idx_1; 创建与约束相关的索引 。可以用using index字句,为与unique和primary key约束相关的索引, 例如: alter table table_na

14、me add constraint PK_primary_keyname primary key (field_name) using index tablespace tablespace_name; 如何创建局部分区索引 。基础表必须是分区表; 。分区数量与基础表相同; 。每个索引分区的子分区数量与相应的基础表分区相同; 。基础表的子分区中的行的索引项,被存储在该索引的相应的子分区中,例 如: Create Index TG_CDR04_SERV_ID_IDX On TG_CDR04(SERV_ID) Pctfree 5 Tablespace TBS_AK01_IDX Storage (

15、MaxExtents 32768 PctIncrease 0 FreeLists 1 FreeList Groups 1 ) local / 如何创建范围分区的全局索引 。基础表可以是全局表和分区表。 create index idx_start_date on tg_cdr01(start_date) global partition by range(start_date) (partition p01_idx vlaues less than (0106) partition p01_idx vlaues less than (0111) partition p01_idx vlaues

16、 less than (0401 ) / 重建现存的索引 重建现存的索引的当前时刻不会影响查询; 重建索引可以删除额外的数据块; 提高索引查询效率; alter index idx_name rebuild nologging; 对于分区索引: alter index idx_name rebuild partition partiton_name nologging; 要删除索引的原因 。不再需要的索引; 。索引没有针对其相关的表所发布的查询提供所期望的性能改善; 。应用没有用该索引来查询数据; 。该索引无效,必须在重建之前删除该索引; 。该索引已经变的太碎了,必须在重建之前删除该索引; 。

17、语句:drop index idx_name;drop index idx_name drop partition partition_name; 建立索引的代价 基础表维护时,系统要同时维护索引,不合理的索引将严重影响系统资源, 主要表现在CPU和I/O上; 插入、更新、删除数据产生大量db file sequential read锁等待; SQL优化器简介 基于规则的优化器 。总是使用索引 。总是从驱动表开始(from子句最右边的表) 。只有在不可避免的情况下,才使用全表扫描 。任何索引都可以 基于成本的优化器 。需要表、索引的统计资料 Analyze table customer com

18、pute statistics; Analyze table customer estimate statistics sample 5000 rows; 。表中设置并行度、表分区 优化器模式 rule模式 。总忽略CBO和统计信息而基于规则 choose模式 。Oracle根据情况选择rule or first_rows or all_rows first_rows 模式 。基于成本,以最快的速度返回记录,会造成总体查询速度的下降或消耗更 多的资源,倾向索引扫描,适合OLTP系统 all_rows模式 。基于成本,确保总体查询时间最短,倾向并行全表扫描 例如: Select last_nam

19、e from customer order by last_name;用first_rows时, 迅速返回记录,但I/O量大,用all_rows时,返回记录慢,但使用资源少。 调整SQL表访问 全表扫描 。返回记录:未排序表40%,排序表7%,建议采用并行机制来提高访问速 度,DDS; 索引访问 。最常用的方法,包括索引唯一扫描和索引范围扫描,OLTP; 快速完全索引扫描 。访问索引中所有数据块,结果相当于全表扫描,可以用索引扫描代替全表 扫描,例如: Select serv_id,count(* ) from tg_cdr01 group by serv_id; 评估全表扫描的合法性 如何实

20、现并行扫描 。永久并行化(不推荐) alter table customer parallel degree 8; 。单个查询并行化 select /*+ full(emp) parallel(emp,8)*/ * from emp; 分区表效果明显 优化SQL语句排序 排序的操作: 。order by 子句 。group by 子句 。select distinct子句 。创建索引时 。union或minus 。排序合并连接 如何避免排序 。添加索引 。在索引中使用distinct子句 。避免排序合并连接 使用提示进行调整 使用提示的原则 。语法:/*+ hint */ 。使用表别名:sel

21、ect /*+ index(e dept_idx)*/ * from emp e 。检验提示 常用的提示 。rule 。all_rows 。first_rows 。use_nl 。use_hash 。use_merge 。index 。index_asc 。no_index 。index_desc(常用于使用max内置函数) 。index_combine(强制使用位图索引) 。index_ffs(索引快速完全扫描) 。use_concat(将查询中所有or条件使用union all) 。parallel 。noparallel 。full 。ordered(基于成本) 调整表连接 表连接的类型

22、 。等连接 where 条件中用等式连接; 。外部连接(左、右连接) 在where条件子句的等式谓词放置一个(+)来实现,例如: select a.ename,m from emp a,bonus b where a.ename=b.ename(+); 该语句返回所有emp表的记录; 。自连接 Select a.value total, B.value hard, (A.value - b.value) soft , Round(b.value/a.value)*100,1) perc From v$sysstat a,v$sysstat b Where a.statistic# = 179

23、and B.statistic# = 180; 反连接 反连接常用于not in or not exists中,是指在查询中找到的任何记录都 不包含在结果集中的子查询;不建议使用not in or not exists; 。半连接 查询中使用exists,含义:即使在子查询中返回多条重复的记录,外部查 询也只返回一条记录。 嵌套循环连接 。被连接表中存在索引的情况下使用; 。使用use_nl。 hash连接 。Hash连接将驱动表加载在内存中,并使用hash技术连接第二个表,提高 等连接速度。 。适合于大表和小表连接; 。使用use_hash。 排序合并连接 。排序合并连接不使用索引 。使用原

24、则: 连接表子段中不存在可用索引; 查询返回两个表中大部分的数据快; CBO认为全表扫描比索引扫描执行的更快。 。使用use_merge 使用临时/中间表 多个大表关联时,可以分别把满足条件的结果集存放到中间表,然后用中间 表关联; SQL子查询的调整 关联与非关联子查询 。关联:子查询的内部引用的是外部表,每行执行一次; 。非关联:子查询只执行一次,存放在内存中。 调整not in 和not exists语句 。可以使用外部连接优化not in子句,例如: select ename from emp where dept_no not in (select dept_no from dept

25、 where dept_name =Math); 改为: select ename from emp,dept where emp.dept_no=dept.dept_no and dept.dept_name is null; 使用索引调整SQL Oracle 为什么不使用索引 。检查被索引的列或组合索引的首列是否出现在PL/SQL语句的WHERE子句 中,这是“执行计划”能用到相关索引的必要条件。 。看采用了哪种类型的连接方式。ORACLE的共有Sort Merge Join(SMJ)、 Hash Join(HJ)和Nested Loop Join(NL)。在两张表连接,且内表的目标列 上

26、建有索引时,只有Nested Loop才能有效地利用到该索引。SMJ即使相关列上 建有索引,最多只能因索引的存在,避免数据排序过程。HJ由于须做HASH运算,索引的存在对数据查询速度几乎没有影响。 。看连接顺序是否允许使用相关索引。假设表emp的deptno列上有索引, 表dept的列deptno上无索引,WHERE语句有emp.deptno=dept.deptno条件。 在做NL连接时,emp做为外表,先被访问,由于连接机制原因,外表的数据访 问方式是全表扫描,emp.deptno上的索引显然是用不上,最多在其上做索引全 扫描或索引快速全扫描。 。是否用到系统数据字典表或视图。由于系统数据字

27、典表都未被分析过,可 能导致极差的“执行计划”。但是不要擅自对数据字典表做分析,否则可能导致 死锁,或系统性能下降。 。索引列是否函数的参数。如是,索引在查询时用不上。 。 是否存在潜在的数据类型转换。 如将字符型数据与数值型数据比较, ORACLE 会自动将字符型用to_number()函数进行转换,从而导致上一种现象的发生。 。是否为表和相关的索引搜集足够的统计数据。对数据经常有增、删、改的 表最好定期对表和索引进行分析,可用SQL语句“analyze table xxxx compute statistics for all indexes;”。ORACLE 掌握了充分反映实际的统计数据

28、,才 有可能做出正确的选择。 。索引列的选择性不高。 我们假设典型情况,有表emp,共有一百万 行数据,但其中的 emp.deptno 列,数据只有 4 种不同的值,如 10、20、30、40。 虽然emp数据行有很多,ORACLE缺省认定表中列的值是在所有数据行均匀分布 的,也就是说每种deptno值各有25万数据行与之对应。假设SQL搜索条件 DEPTNO=10, 利用deptno列上的索引进行数据搜索效率, 往往不比全表扫描的高。 。索引列值是否可为空(NULL)。如果索引列值可以是空值,在SQL语句中 那些要返回NULL值的操作,将不会用到索引,如COUNT(*),而是用全表扫描。 这

29、是因为索引中存储值不能为全空。 。看是否有用到并行查询(PQO)。并行查询将不会用到索引。 。 如果从以上几个方面都查不出原因的话, 我们只好用采用在语句中加hint 的方式强制ORACLE使用最优的“执行计划”。 hint采用注释的方式,有行 注释和段注释两种方式。 如我们想要用到A表的IND_COL1索引的话,可采用 以下方式: “SELECT /*+ INDEX(A IND_COL1)*/ * FROM A WHERE COL1 = XXX;“ 如何屏蔽索引 语句的执行计划中有不良索引时,可以人为地屏蔽该索引,方法: 。数值型:在索引字段上加0,例如 select * from emp

30、where emp_no+0 = v_emp_no; 。字符型:在索引字段上加,例如 select * from tg_cdr01 where msisdn|=v_msisdn; Oracle优化经典文章-索引原理篇 Oracle提供了大量索引选项。知道在给定条件下使用哪个选项对于一个应用程 序的性能来说非常重要。一个错误的选择可能会引发死锁,并导致数据库性能急 剧下降或进程终止。而如果做出正确的选择,则可以合理使用资源,使那些已经 运行了几个小时甚至几天的进程在几分钟得以完成, 这样会使您立刻成为一位英 雄。这篇文章就将简单的讨论每个索引选项。主要有以下内容: 1 基本的索引概念 查询DBA

31、_INDEXES视图可得到表中所有索引的列表,注意只能通过 USER_INDEXES的方法来检索模式(schema)的索引。访问USER_IND_COLUMNS视图 可得到一个给定表中被索引的特定列。 2 组合索引 当某个索引包含有多个已索引的列时,称这个索引为组合(concatented) 索引。在 Oracle9i引入跳跃式扫描的索引访问方法之前,查询只能在有限条件 下使用该索引。比如:表emp有一个组合索引键,该索引包含了empno、ename 和deptno。在Oracle9i之前除非在where之句中对第一列(empno)指定一个 值,否则就不能使用这个索引键进行一次范围扫描。 特别

32、注意:在Oracle9i之前,只有在使用到索引的前导索引时才可以使用 组合索引! 3 ORACLE ROWID 通过每个行的ROWID,索引Oracle提供了访问单行数据的能力。ROWID其实 就是直接指向单独行的线路图。如果想检查重复值或是其他对ROWID本身的引 用,可以在任何表中使用和指定rowid列。 4 限制索引 限制索引是一些没有经验的开发人员经常犯的错误之一。 在SQL中有很多陷 阱会使一些索引无法使用。下面讨论一些常见的问题: 4.1 使用不等于操作符(、!=) 下面的查询即使在cust_rating列有一个索引, 查询语句仍然执行一次全表 扫描。 select cust_Id

33、,cust_name from customers where cust_rating aa; 把上面的语句改成如下的查询语句,这样,在采用基于规则的优化器而不是 基于代价的优化器(更智能)时,将会使用索引。 select cust_Id,cust_name from customers where cust_rating aa; 特别注意:通过把不等于操作符改成OR条件,就可以使用索引,以避免全 表扫描。 4.2 使用IS NULL 或IS NOT NULL 使用 IS NULL 或 IS NOT NULL 同样会限制索引的使用。因为 NULL 值并没有 被定义。在SQL语句中使用NULL会

34、有很多的麻烦。因此建议开 发人员在建 表时,把需要索引的列设成NOT NULL。如果被索引的列在某些行中存在NULL值, 就不会使用这个索引(除非索引是一个位图索 引,关于位图索引在稍后在 详细讨论)。 4.3 使用函数 如果不使用基于函数的索引, 那么在SQL语句的WHERE子句中对存在索引的 列使用函数时,会使优化器忽略掉这些索引。 下面的查询不会使用索引(只要它不是基于函数的索引) select empno,ename,deptno from emp where trunc(hiredate)=01-MAY-81; 把上面的语句改成下面的语句,这样就可以通过索引进行查找。 select

35、empno,ename,deptno from emp where hiredate(to_date(01-MAY-81)+0.9999); 4.4 比较不匹配的数据类型 比较不匹配的数据类型也是比较难于发现的性能问题之一。 注意下面查询的例子,account_number是一个VARCHAR2类型,在 account_number字段上有索引。下面的语句将执行全表扫描。 select bank_name,address,city,state,zip from banks where account_number = 990354; Oracle可以自动把where子句变成to_number(

36、account_number)=990354, 这样就限制了索引的使用,改成下面的查询就可以使用索引: select bank_name,address,city,state,zip from banks where account_number =990354; 特别注意:不匹配的数据类型之间比较会让Oracle自动限制索引的使用, 即便对这个查询执行Explain Plan也不能让您明白为什么做了一 次“全表扫描”。 5 选择性 使用USER_INDEXES视图,该视图中显示了一个distinct_keys列。比较一 下唯一键的数量和表中的行数,就可以判断索引的选择性。选择性越高,索引返

37、回的数据就越少。 6 群集因子(Clustering Factor) Clustering Factor位于USER_INDEXES视图中。该列反映了数据相对于已 索引的列是否显得有序。如果Clustering Factor列的值接近于索引中的树叶块 (leaf block)的数目,表中的数据就越有序。如果它的值接近于表中的行数,则 表中的数据就不是很有序。 7 二元高度(Binary height) 索引的二元高度对把ROWID返回给用户进程时所要求的I/O量起到关键作 用。在对一个索引进行分析后,可以通过查询DBA_INDEXES的B-level列查看它 的二元高度。 二元高度主要随着表的

38、大小以及被索引的列中值的范围的狭窄程度 而变化。索引上如果有大量被删除的行,它的二元高度也会增加。更新索引列也 类似于删除操作, 因为它增加了已删除键的数目。 重建索引可能会降低二元高度。 8 快速全局扫描 在Oracle7.3后就可以使用快速全局扫描(Fast Full Scan)这个选项。这个 选项允许Oracle执行一个全局索引扫描操作。快速全局扫描读取B-树索引上所 有树叶块。 初始化文件中的DB_FILE_MULTIBLOCK_READ_COUNT参数可以控制同时 被读取的块的数目。 9 跳跃式扫描 从Oracle9i开始,索引跳跃式扫描特性可以允许优化器使用组合索引,即 便索引的前

39、导列没有出现在WHERE子句中。 索引跳跃式扫描比全索引扫描要快的 多。下面的程序清单显示出性能的差别: create index skip1 on emp5(job,empno); index created. select count(*) from emp5 where empno=7900; Elapsed:00:00:03.13 Execution Plan 0 SELECT STATEMENT Optimizer=CHOOSE(Cost=4 Card=1 Bytes=5) 1 0 SORT(AGGREGATE) 2 1 INDEX(FAST FULL SCAN) OF SKIP1(

40、NON-UNIQUE) Statistics 6826 consistent gets 6819 physical reads select /*+ index(emp5 skip1)*/ count(*) from emp5 where empno=7900; Elapsed:00:00:00.56 Execution Plan 0 SELECT STATEMENT Optimizer=CHOOSE(Cost=6 Card=1 Bytes=5) 1 0 SORT(AGGREGATE) 2 1 INDEX(SKIP SCAN) OF SKIP1(NON-UNIQUE) Statistics 2

41、1 consistent gets 17 physical reads 10 索引的类型 B-树索引 位图索引 HASH索引 索引编排表 反转键索引 基于函数的索引 分区索引 本地和全局索引 优化Oracle 内在索引和参数数的调整 一些较为常见的变更: 1、针对 Oracle 参数的更改。对 optimizer_mode,optimizer_index_cost_adj 和 optimizer_index_caching的改变能对 SQL执行计划产生巨大影响。 2、 针对统计参数的更改。使用 dbms_stats 包导入特定的统计参数(针对当然处理模 式作了调整的)可对 SQL的执行速度产生

42、巨大影响。 3、 使用自动化查询重新写入。使用 Oracle实体化视图能够预先聚集、预先汇总数据, 从而减少运行时刻表连接的数量。对于更新比较少的数据库,也可以通过预先连接表来提高 处理速度。 一些对性能调优最重要的 Oracle优化参数如下: * optimizer_mode(优化模式)在 Oracle 9i 中,有许多优化模式,都是由参数 optimizer_mode的值决定的。 这个参数的取值范围是rule, choose, all_rows, first_rows, first_rows_1, first_rows_10 和 first_rows_100. 我们以定义“最好的”执行计划

43、作为开始点。在任何给定的时间,库缓冲区中的所有 SQL语句都需要有“最好的”执行计划(当然,由于在任何给定的时间里处理需求可能不同, 所以这个最优执行计划可能会经常发生变化) 。什么是“最好的”执行计划?是返回结果最 快的执行计划还是使用最少计算资源的执行计划?很明显, 答案依赖于你的数据库的处理过 程,Oracle提供了两种优化模式,允许你选择你认为的“最好的”执行计划: 1、 optimizer_mode=first_rows 相对全表扫描访问,这个优化模式更注重索引访 问。当你想要一个查询以最快的速度返回结果行时,即使它的逻辑输入输出总量比全表扫描 高,也要使用这个模式在线访问系统一般都

44、使用这个模式,因为终端用户想要尽快地看到第 一页查询结果。 2、optimizer_mode=all_rows 这个优化模式更注重全表扫描(特别是并发全表扫 描) ,因为在这种情况下服务器资源的开销最小。这个模式一般被用于批处理进程和数据仓 库中,它们的目标都是使服务器消耗的资源最小化。 3、 optimizer_mode=first_rows_n 从 Oracle 9i 开始,又有一种新的优化模式针 对某些返回小结果集的查询进行优化。其取值范围是 first_rows_1, first_rows_10 和 first_rows_100,使用这些参数值可以确保 Oracle能够优化这类 SQL

45、。 虽然参数 optimizer_mode 控制了“基于代价的优化”的总体行为,还有其他 Oracle 参数也会对“基于代价的优化”产生相当大的影响。Oracle 提供了一些重要的参数来控制 “基于代价的优化”做出的选择: 1、optimizer_index_cost_adj 这个参数可用来调整“基于代价的优化”相对于全 表扫描访问而言,更加倾向于索引访问的程度。这个值越小, “基于代价的优化”就越有可 能使用一个可用的索引。 2 、 optimizer_index_caching 这个参数告诉 Oracle你的索引在内存的数据缓冲区 中的可能性有多大。对这个参数的设置将会影响到“基于代价的优

46、化” 做出的对一个表连 接(嵌套循环)使用索引还是使用全表扫描选择。 3、 db_file_multiblock_read_count 当把这个值设置得比较大时(使用更大的服 务器) , “基于代价的优化”识别出分散的(多块)读操作的代价或许比识别顺序读操作的代 价更小一些。这就使得“基于代价的优化”更加倾向于全表扫描。 但是从 Oracle 9.2版本开始,情况不再是这样了。当计算系统统计表时,它包含了“多 块读操作记数” (MBRC) ,这个数字决定了全表扫描的成本。Oracle 10g 则更进一步,加入 了一些“系统默认值” ,这些默认值是非常不合适的。对于 Oracle 9.2 版本而

47、言,请注意 Metalink上的149560.1。 1、 parallel_automatic_tuning 当该参数设置为“开启”时,对于含有许多 CPU 的 Oracle 服务器,全表扫描并发执行。因为并发全表扫描的速度可以非常快,所以“基于 代价的优化”对于索引访问开销很大,因此更加倾向于使用全表扫描。 2、 hash_area_size(假如不使用pga_aggregate_target 的话) 这个参数设置“基 于代价的优化” 相对于使用嵌套循环和排序合并表连接来说, 更倾向于使用哈希连接的程度。 3、sort_area_size(只当不使用参数 pga_aggregate_target 时) 这个参数影响了 “基于代价的优化” 做出的执行索引访问还是执行对结果集的排序的决定。 这个参数值越高, 则在内存中执行排序(比使用临时表空间快上千倍)的可能性就越大,同时“基于代价的优 化”相对于使用预先排序好的索引检索,更倾向于使用直接排序。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报