Oracle优化器和索引原理
================ Oracle优化器
Oracle
的优化器(Optimizer)实际上是数据库环境的参数设置。可以在INITsid.ORA文件内的OPTIMZER_MODE=RULE或OPTIMZER_MODE=COST或OPTIMZER_MODE=CHOOSE来设置优化目标。用户也可以在会话和查询方式下更改优化器的默认操作模式。
如果OPTIMZER_MODE=RULE,则激活基于规则的优化器(RBO)。基于规则的优化器按照一系列的语法规则来推测可能执行路径和比较可替换的执行路径。
如果OPTIMZER_MODE=COST,则激活基于成本的优化器(CBO)。它使用ANALYZE语句来生成数据库对象的统计数据。这些统计数据包括表的行数、平均长度及索引中不同的关键字数等。基于这些统计数据,成本优化器可以计算出可获得的执行路径的成本。并选择具有最小的成本执行路径。在CBO模式下,需要经常运行ANALYZE
命令来确保数据的准确性。
如果OPTIMZER_MODE=CHOOSE,则在表被分析的情况下激活基于成本的优化器。但当一个查询分析的表是未被ANALYZE分析统计过的时侯,CBO优化器就决定进行全表扫描操作。所以为了减少可能的全表扫描,应该尽量避免使用OPTIMZER_MODE=CHOOSE选项。
Oracle 9i第二版将是最后一个正式支持CBO的版本。
Oracle推荐所有合作伙伴和客户验证使用CBO的应用程序,
尽管RBO在Oracle10i(现在称Oracle10G)仍然可用,但不受支持。
作为每一个已发布的Oracle笔记中,RBO的存在妨碍了Oralce对查询处理引擎的关键增强.
它的移除将允许Oracle提高数据库引擎查询处理组件的性能和可靠性。
目前,Oracle 对RBO的支持仅仅用以有限的错误修正并且Oracle对RBO没有添加新的功能.
CBO主要获益如下:
1.以后Oracle停止RBO环境的开发.
2.随后的Oracle数据库将移除RBO
3.同CBO相比,RBO的访问方法是有限数量的.
4.所有新功能基于CBO,这些大多数新功能对于设置等等是重要的。簇索引表,位图索引,基于函数的索引,反向索引,哈希连接,物化视图,索引表,和并行查询, 星型连接等
5.媒介链接支持.
6.一旦RBO不受支持,Oracle支持也不可用。
7.CBO已经成熟
先前Oracle7中,RBO在某些场景胜过CBO,甚至CBO并不是如想像中完好,并且经常选择糟糕的执行计划。以后的发行版本中,CBO功能获得了提升,现在对于新功能,它提供了对考虑收益的较好交互性
8.分布式和远程查询更加可靠
在RBO中,数据库链接,从本地到远程数据库多于一个表的查询调整相当困难.同样的工作,CBO胜过了RBO。本地优化器知道远程表的目前统计信息,并且对于执行计划能做出更好的决定.RBO可能考虑远程数据库的索引,但是CBO有权利统计远程数据库索引的信息并对查询计划做出决定.
=============== 关于 CBO
当系统使用CBO方式优化SQL的时候,要使其执行计划达到最优化,需要定期执行数据统计,必须保证统计数据的及时性,否则可能得不到预计的优化效果,或与预计的优化效果相差悬殊。
要对数据库对象生成统计信息,可以有以下方法:
完全统计法:analyze table table_name compute statistics;
抽样估计法:analyze table table_name estimate statistics sample 30 percent;
对表使用抽样估计法要比完全统计法的生成统计速度要快,但是统计数据可能不够精确。在开发过程中,我们可能要涉及很多的表的查询,而我们在使用CBO的时候就需要经常对这些表执行分析统计,得到CBO所需要的统计数据。通常有以下几种方法来收集统计信息:
1.导出所有需要分析的表的语句脚本,然后执行该脚本。
SQL> SPOOL OFF;
SQL> SPOOL C:/ANALYZE_TAB.SQL
SQL> SELECT 'ANALYZE TABLE '||OWNER||'.'||TABLE_NAME||' COMPUTE STATISTICS;' FROM ALL_TABLES WHERE OWNER NOT IN ('SYS','SYSTEM');
然后调整一下脚本,并执行:
SQL>@C:/ANALYZE_TAB.SQL
可以将该脚本放到服务器端并设置自动执行。
2.使用Oracle提供的过程:DBMS_DDL.ANALYZE_OBJECT,该过程可以对某个特定用户的特定表执行统计。例如:
完全统计:
SQL>execute dbms_ddl.analyze_object('TABLE','DINYAR','DINYA_TEST01','COMPUTE');
PL/SQL procedure successfully completed
50%抽样统计
SQL>execute dbms_ddl.analyze_object('TABLE','DINYAR','DINYA_TEST01','ESTIMATE',NULL,50);
PL/SQL procedure successfully completed
SQL>
可以使用该过程,生成分析统计数据库对象的脚本,并定时执行该脚本。
3.使用Oracle提供的过程DBMS_UTILITY.ANALYZE_SCHEMA该过程执行对某个特定用户下的TABLE,INDEX和CLUSTER的分析统计。如:
完全统计SCHEMA下的所有对象:
SQL> execute dbms_utility.analyze_schema('DINYAR','COMPUTE');
PL/SQL procedure successfully completed
Executed in 6.9 seconds
SQL>
抽样50%统计SCHEMA下的所有对象:
SQL> execute dbms_utility.analyze_schema('DINYAR','ESTIMATE',NULL,50);
PL/SQL procedure successfully completed
Executed in 1.933 seconds
SQL>
从执行的时间上看,抽样统计的时间要比完全统计所花费的时间要短,执行的更快。
4.使用Oracle提供的过程DBMS_UTILITY.ANALYZE_DATABASE,该过程可以对整个数据库中的对象进行分析统计。但需要当前登陆用户具备足够的权限,否则系统将提示出错。如:
SQL> execute dbms_utility.analyze_database('COMPUTE');
begin dbms_utility.analyze_database('COMPUTE'); end;
ORA-20000: You have insufficient privileges for an object in this database.
ORA-06512: at "SYS.DBMS_UTILITY", line 501
ORA-06512: at line 1
SQL>
改换有DBA权限的用户登陆:
SQL> execute dbms_utility.analyze_database('COMPUTE');
begin dbms_utility.analyze_database('COMPUTE'); end;
ORA-30657: operation not supported on external organized table
ORA-06512: at "SYS.DBMS_DDL", line 179
ORA-06512: at "SYS.DBMS_UTILITY", line 497
ORA-06512: at line 1
SQL>
从上面的错误信息可以看出,不支持对外部表的分析统计,查看Oracle的解决办法,Oracle称不要试图做这项操作。
DBMS_UTILITY.ANALYZE_DATABASE的抽样分析统计和上例中类似。
5.使用Oracle提供的过程:DBMS_STATS,该包中的过程dbms_stats.gather_index_stats,
DBMS_STATS.gather_table_stats,DBMS_STATS.gather_schema_stats,DBMS_STATS.gather_database_stats,DBMS_STATS.gather_system_stats分别执行对索引、表、某个schema、数据库、系统的统计信息。例如:
SQL> execute dbms_stats.gather_table_stats('DINYAR','DINYA_TEST01');
PL/SQL procedure successfully completed
Executed in 0.29 seconds
SQL> execute dbms_stats.gather_schema_stats('DINYAR');
PL/SQL procedure successfully completed
Executed in 7.07 seconds
SQL>
(该包中还有其他的一些过程,可以对数据库的对象进行操作,不在这里讨论。)
6.定时执行分析统计,使用DBMS_JOB包,创建一个JOB,定时执行过程,对数据库对象进行分析统计:
PL/SQL procedure successfully completed
Executed in 0.581 seconds
job_num
--------
41
SQL>
这样就可以在数据库中定时执行数据库对象统计信息的收集,保证了使用CBO优化器优化时优化路径的准确性。
=============== 关于索引
Oracle索引原理
栏 目 树 形 导 航
没有公告
解决方案首页 · 视频通信 · IPTV与流媒体 · 3G与移动多媒体 · 视频监控
标准专题首页 | 3G | VOIP | NGN | IPV6 | AVS | SIP | H.264 | H.323 | H.324M | QOS
| MPEG | 音频编码 | 防火墙穿越| IPTV
开发专题首页 · Visual C++ · 数据库技术 · 嵌入式操作系统 · Java · .Net · Jsp
您现在的位置: 中国视讯技术网 >> 技术开发 >> 数据库 >> Oracle >> ORACLE应用 >> 文章正文 用户登录 新用户注册
Oracle索引原理
Oracle索引原理
副标题:
作者:佚名 文章来源:不详 点击数:22 更新时间:2006-7-28 17:44:16
Oracle提供了大量索引选项。知道在给定条件下使用哪个选项对于一个应用程序的性能来说非常重要。一个错误的选择可能会引发死锁,并导致数据库性能急剧下降或进程终止。而如果做出正确的选择,则可以合理使用资源,使那些已经运行了几个小时甚至几天的进程在几分钟得以完成,这样会使您立刻成为一位英雄。这篇文章就将简单的讨论每个索引选项。主要有以下内容:
[1] 基本的索引概念
查询DBA_INDEXES视图可得到表中所有索引的列表,注意只能通过USER_INDEXES的方法来检索模式(schema)的索引。访问USER_IND_COLUMNS视图可得到一个给定表中被索引的特定列。
[2] 组合索引
当某个索引包含有多个已索引的列时,称这个索引为组合(concatented)索引。在
Oracle9i引入跳跃式扫描的索引访问方法之前,查询只能在有限条件下使用该索引。比如:表emp有一个组合索引键,该索引包含了empno、
ename和deptno。在Oracle9i之前除非在where之句中对第一列(empno)指定一个值,否则就不能使用这个索引键进行一次范围扫描。
特别注意:在Oracle9i之前,只有在使用到索引的前导索引时才可以使用组合索引!
[3] ORACLE ROWID
通过每个行的ROWID,索引Oracle提供了访问单行数据的能力。ROWID其实就是直接指向单独行的线路图。如果想检查重复值或是其他对ROWID本身的引用,可以在任何表中使用和指定rowid列。
[4] 限制索引
限制索引是一些没有经验的开发人员经常犯的错误之一。在SQL中有很多陷阱会使一些索引无法使用。下面讨论一些常见的问题:
4.1 使用不等于操作符(<>、!=)
下面的查询即使在cust_rating列有一个索引,查询语句仍然执行一次全表扫描。
select cust_Id,cust_name
from customers
where cust_rating <> 'aa';
把上面的语句改成如下的查询语句,这样,在采用基于规则的
优化器而不是基于代价的优化器(更智能)时,将会使用索引。
select cust_Id,cust_name
from customers
where cust_rating < 'aa' or cust_rating > 'aa';
特别注意:通过把不等于操作符改成OR条件,就可以使用索引,以避免全表扫描。
4.2 使用IS NULL 或IS NOT NULL
使用IS NULL 或IS NOT
NULL同样会限制索引的使用。因为NULL值并没有被定义。在SQL语句中使用NULL会有很多的麻烦。因此建议开发人员在建表时,把需要索引的列设成NOT
NULL。如果被索引的列在某些行中存在NULL值,就不会使用这个索引(除非索引是一个位图索引,关于位图索引在稍后在详细讨论)。
4.3 使用函数
如果不使用基于函数的索引,那么在SQL语句的WHERE子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引。
下面的查询不会使用索引(只要它不是基于函数的索引)
select empno,ename,deptno
from emp
where trunc(hiredate)='01-MAY-81';
把上面的语句改成下面的语句,这样就可以通过索引进行查找。
select 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(account_number)=990354,这样就限制了
索引的使用,改成下面的查询就可以使用索引:
select bank_name,address,city,state,zip
from banks
where account_number ='990354';
特别注意:不匹配的数据类型之间比较会让Oracle自动限制索引的使用,
即便对这个查询执行Explain Plan也不能让您明白为什么做了一次“全表扫描”。
[5] 选择性
使用USER_INDEXES视图,该视图中显示了一个distinct_keys列。比较一下唯一键的数量和表中的行数,就可以判断索引的选择性。选择性越高,索引返回的数据就越少。
[6] 群集因子(Clustering Factor)
Clustering
Factor位于USER_INDEXES视图中。该列反映了数据相对于已索引的列是否显得有序。如果Clustering
Factor列的值接近于索引中的树叶块(leaf
block)的数目,表中的数据就越有序。如果它的值接近于表中的行数,则表中的数据就不是很有序。
[7] 二元高度(Binary height)
索引的二元高度对把ROWID返回给用户进程时所要求的I/O量起到关键作用。在对一个索引进行分析后,可以通过查询DBA_INDEXES的B-
level列查看它的二元高度。二元高度主要随着表的大小以及被索引的列中值的范围的狭窄程度而变化。索引上如果有大量被删除的行,它的二元高度也会增加。更新索引列也类似于删除操作,因为它增加了已删除键的数目。重建索引可能会降低二元高度。
[8] 快速全局扫描
在Oracle7.3后就可以使用快速全局扫描(Fast Full
Scan)这个选项。这个选项允许Oracle执行一个全局索引扫描操作。快速全局扫描读取B-树索引上所有树叶块。初始化文件中的
DB_FILE_MULTIBLOCK_READ_COUNT参数可以控制同时被读取的块的数目。
[9] 跳跃式扫描
从Oracle9i开始,索引跳跃式扫描特性可以允许优化器使用组合索引,即便索引的前导列没有出现在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'(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
21 consistent gets
17 physical reads
[10] 索引的类型
B-树索引
位图索引
HASH索引
索引编排表
反转键索引
基于函数的索引
分区索引
本地和全局索引
发表评论
-
查看当前Session SQL
2014-07-08 11:51 1092SELECT (SELECT listagg(b.sql_te ... -
CLOB列 XML信息查看
2014-05-28 10:28 1027--使用该SQL查询节点情况 SELECT * FROM ... -
【转】ORACLE 临时表空间使用率过高的原因及解决方案
2012-12-25 15:24 1021http://www.cnblogs.com/wonder31 ... -
oracle:获取session的IP地址
2012-10-20 02:38 4311方法1 创建触发器: create orreplace ... -
Oracle ora-01002
2012-08-11 02:43 28957ORA-01002:fetch超出序列 ... -
提高Oracle SQL的执行效率的3个方案
2012-08-08 00:57 1005如果你想要提高Oracle SQL ... -
Oracle STA
2012-08-06 11:32 0第一步:创建优化任务 ... -
Oracle SQL小技巧
2012-08-06 11:21 01.两个字段可空的判断相等,用decode判断。 例子:d ... -
自动工作负载库(Automatic Workload Repository,AWR)
2012-07-23 22:45 1430自动工作负载库(Automatic Workload Repo ... -
orace的隔离级别
2012-07-21 01:06 1107隔离级别(isoation eve) 隔离级别定义了事务与 ... -
Oracle SQLID 与 Hash_value 之间的相互转化
2012-07-20 00:55 4720一、什么是SQLID SQLID是根据SQL 文本,经过 ... -
Oracle优化器的RBO和CBO方式
2012-07-13 00:25 2404[/size]Or[size=large][size=smal ... -
Oracle 优化器详解
2012-07-13 00:18 1357一、优化器基本知识 Oracle在执行一个SQL之前,首先 ... -
SQL中使用WITH AS提高性能
2012-07-05 23:30 1256摘要:本文结合笔者实 ... -
Ibatis调用Oracle存储过程,以及返回Cursor结果集的问题
2012-07-01 23:46 2139最近开始接触Oracle了,接触的越多越感受到自己的渺小!(o ... -
Oracle表连接操作——Hash Join(哈希连接
2012-05-20 17:05 0连接 http://space.itpub.net/?uid ... -
Oracle hash join
2012-05-20 17:00 955hash join是oracle里面一个 ... -
转--一次HASH JOIN 临时表空间不足的分析和优化思路
2012-05-20 15:36 4558最近遇到一个语句, 只要一执行这个语句就会出现报错临时表空间 ... -
SQL*PLUS SET 变量
2012-05-02 22:46 882SQL*PLUS SET变量 SQL*PLUS维护系 ... -
转---借助内存表处理复杂的oracle查询要求.
2012-03-25 23:23 1423借助内存表处理复杂的oracle查询要求. 在日常业务处理过 ...
相关推荐
2. **分析表统计信息**:对`mailsend`表进行了分析,计算统计信息,帮助Oracle优化器更好地选择执行计划。 3. **使用EXISTS代替IN**:将原SQL语句中的IN子句替换为EXISTS子句,以减少不必要的全表扫描,提高查询性能...
本篇将深入探讨Oracle优化的基本原理和实用的SQL优化技巧。 首先,了解Oracle优化的基本原理至关重要。Oracle数据库采用了一个名为“查询优化器”(Query Optimizer)的组件,它在执行SQL语句前会分析多种可能的...
3. **索引重构**:通过重新创建或优化索引来改善索引的存储结构,从而提高查询性能的过程。 #### 三、索引重构方式及其特点 ##### 1. DROP AND RECREATE(完全重建) - **定义**:首先删除旧索引,然后重新创建一...
Oracle数据库设计优化是提升系统性能和数据管理效率的关键环节。此指导旨在为CRM产品的数据库设计提供一套规范,以确保数据库设计的质量,进而提高软件产品的整体质量。该规范主要针对CRM各产品的数据库设计人员,...
以上知识点均来自“ORACLE原厂资料CONCEPTS”中提供的内容,这本书深入讲解了Oracle数据库的各个方面,从基础的数据库概念到复杂的优化和管理技术。对于Oracle数据库的管理员和开发人员而言,这本书是学习和参考的...
Oracle 9i是Oracle数据库的一个重要版本,发布于2001年,它引入了许多创新特性和优化,提升了性能、可用性和可管理性。这份"Oracle 9i原厂培训PPT"是一个宝贵的教育资源,它涵盖了Oracle 9i数据库管理员(DBA)需要...
Oracle支持多种类型的索引,如B树索引、位图索引、函数索引等。理解何时使用不同类型的索引及其对性能的影响至关重要。 5. **视图**:视图是虚拟表,基于一个或多个表的查询结果。它们用于简化复杂的查询,提供数据...
此外,Oracle支持多种数据库对象,如视图(Views)、索引(Indexes)、存储过程(Stored Procedures)和触发器(Triggers),这些对象能够提高数据管理和查询效率。 在Oracle中,SQL(Structured Query Language)...
3. **性能优化**:涉及SQL查询优化,如使用EXPLAIN PLAN分析查询执行计划,索引策略的选取,以及如何使用Oracle的性能监控工具如SQL*Plus、 tkprof 和AWR报告进行性能诊断。 4. **备份与恢复**:介绍Oracle的备份...
7. **SQL优化**:Oracle 10g提供了强大的SQL优化器,能够根据统计信息选择最佳执行计划,提升查询性能。此外,还引入了SQL Profile和SQL Plan Baseline来进一步改善查询性能。 8. **PL/SQL**:Oracle的编程语言,...
这套教材详细深入地介绍了ORACLE 11G的各种特性和功能,旨在帮助用户提升在数据库管理、开发和优化方面的专业技能。对于那些勇于挑战OCP(Oracle Certified Professional)认证的学员来说,这套教材无疑是宝贵的参考...
- 如果索引未被使用,可能是因为查询优化器选择了全表扫描。可以通过调整SQL语句或使用`FORCE INDEX`强制使用索引。 5. **并行执行**: - 对于非常大的表,可以考虑启用并行查询来加速处理。使用`PARALLEL`选项在...
Oracle OCM,全称为Oracle Certified Master,是Oracle公司为高级数据库管理员提供的顶级认证,旨在证明其在Oracle数据库管理、性能优化、故障排除等方面具备高级技术和专业知识。本套教材聚焦于Oracle OCM原厂培训...
- 使用Oracle提示:通过SQL提示(hints)可以指导Oracle优化器选择更高效的执行路径。 - 避免全表扫描:尽量让查询利用索引,减少对磁盘I/O的依赖。 - 减少并行操作:过多的并行操作可能导致资源竞争,适当降低...
Oracle 9i数据库性能优化是IT领域中一个关键的话题,特别是在大型企业或组织中,数据库的性能直接影响到系统的响应速度和服务质量。Oracle OCP(Oracle Certified Professional)是Oracle公司为数据库管理员提供的...
这个工作坊旨在帮助数据库管理员(DBA)深入理解Oracle 10g数据库的高级特性和管理技术,提升其在数据库性能优化、故障排除、备份与恢复等方面的能力。 在Oracle 10g中,一些核心知识点包括: 1. 数据库概念:理解...
Oracle 11g OCP(Oracle Certified Professional)是Oracle公司为数据库管理员(DBA)提供的专业认证,旨在证明持证者具有管理和维护Oracle 11g数据库系统的高级技能。这个认证涵盖了从安装配置、性能优化到故障排查...
通过原厂培训,用户可以学习到如何有效地管理、维护和优化Oracle数据库,这对于数据库管理员(DBA)和开发人员来说至关重要。 在PDF部分,可能会包含以下知识点: 1. **Oracle数据库架构**:讲解Oracle数据库的...
1. **Oracle数据库基础**:这部分内容会介绍Oracle数据库的基本概念,如关系型数据库模型、SQL语言基础、数据类型、表和索引的创建与管理,以及数据库的启动、关闭和备份恢复。 2. **数据库管理**:深入学习Oracle...