`

分析Oracle有时会用索引来查找数据的原因

 
阅读更多

转:http://www.webjx.com/database/oracle-140.html

 

 

问:为什么Oracle有时会用索引来查找数据?

答:在你运用SQL语言,向数据库发布一条查询语句时,Oracle将伴随产生一个“执行计划”,也就是该语句将通过何种数据搜索方案执行,是通过全表扫描、还是通过索引搜寻等其它方式。搜索方案的选用与Oracle的优化器息息相关。

SQL语句的执行步骤

一条SQL语句的处理过程要经过以下几个步骤。

1 语法分析 分析语句的语法是否符合规范,衡量语句中各表达式的意义。

2 语义分析 检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限。

3 视图转换 将涉及视图的查询语句转换为相应的对基表查询语句。

4 表达式转换 将复杂的SQL表达式转换为较简单的等效连接表达式。

5 选择优化器 不同的优化器一般产生不同的“执行计划”

6 选择连接方式 Oracle有三种连接方式,对多表连接Oracle可选择适当的连接方式。

7 选择连接顺序 对多表连接Oracle选择哪一对表先连接,选择这两表中哪个表做为源数据表。

8 选择数据的搜索路径 根据以上条件选择合适的数据搜索路径,如是选用全表搜索还是利用索引或是其他的方式。

9 运行“执行计划”

Oracle的优化器

Oracle有两种优化器:基于规则的优化器(RBO, Rule Based Optimizer),和基于代价的优化器(CBO, Cost Based Optimizer)。

RBO自Oracle 6版以来被采用,有着一套严格的使用规则,只要你按照它去写SQL语句,无论数据表中的内容怎样,也不会影响到你的“执行计划”,也就是说对数据不“敏感”,Oracle公司已经不再发展这种技术了。

CBO自Oracle 7版被引入,Oracle自7版以来采用的许多新技术都是基于CBO的,如星型连接排列查询,哈希连接查询,和并行查询等。CBO计算各种可能“执行计划”的“代价”,即cost,从中选用cost最低的方案,作为实际运行方案。各“执行计划”的cost的计算根据,依赖于数据表中数据的统计分布,Oracle数据库本身对该统计分布并不清楚,须要分析表和相关的索引,才能搜集到CBO所需的数据。

一般而言,CBO所选择的“执行计划”都不会比RBO的“执行计划”差,而且相对而言,CBO对程序员的要求没有RBO那么苛刻,节省了程序员为了从多个可能的“执行计划”中选择一个最优的方案而花费的调试时间,但在某些场合下也会存在问题。

较典型的问题有:有时,表明明建有索引,但查询过程显然没有用到相关的索引,导致查询过程耗时漫长,占用资源巨大,问题到底出在哪儿呢?按照以下顺序查找,基本上能发现原因所在。

查找原因的步骤

首先,我们要确定数据库运行在何种优化模式下,相应的参数是:optimizer_mode。可在svrmgrl中运行“show parameter optimizer_mode"来查看。Oracle V7以来缺省的设置应是"choose",即如果对已分析的表查询的话选择CBO,否则选择RBO。如果该参数设为“rule”,则不论表是否分析过,一概选用RBO,除非在语句中用hint强制。

其次,检查被索引的列或组合索引的首列是否出现在PL/SQL语句的WHERE子句中,这是“执行计划”能用到相关索引的必要条件。

第三,看采用了哪种类型的连接方式。Oracle的共有Sort Merge Join(SMJ)、Hash Join(HJ)和Nested Loop Join(NL)。在两张表连接,且内表的目标列上建有索引时,只有Nested Loop才能有效地利用到该索引。SMJ即使相关列上建有索引,最多只能因索引的存在,避免数据排序过程。HJ由于须做HASH运算,索引的存在对数据查询速度几乎没有影响。

第四,看连接顺序是否允许使用相关索引。假设表emp的deptno列上有索引,表dept的列deptno上无索引,Where语句有emp.deptno=dept.deptno条件。在做NL连接时,emp做为外表,先被访问,由于连接机制原因,外表的数据访问方式是全表扫描,emp.deptno上的索引显然是用不上,最多在其上做索引全扫描或索引快速全扫描。

第五,是否用到系统数据字典表或视图。由于系统数据字典表都未被分析过,可能导致极差的“执行计划”。但是不要擅自对数据字典表做分析,否则可能导致死锁,或系统性能下降。

第六,索引列是否函数的参数。如是,索引在查询时用不上。

第七,是否存在潜在的数据类型转换。如将字符型数据与数值型数据比较,Oracle会自动将字符型用to_number()函数进行转换,从而导致第六种现象的发生。

第八,是否为表和相关的索引搜集足够的统计数据。对数据经常有增、删、改的表最好定期对表和索引进行分析,可用SQL语句:

analyze table xxxx compute statistics for all indexes;

Oracle掌握了充分反映实际的统计数据,才有可能做出正确的选择。

第九,索引列的选择性不高。

我们假设典型情况,有表emp,共有一百万行数据,但其中的emp.deptno列,数据只有4种不同的值,如10、20、30、40。虽然emp数据行有很多,Oracle缺省认定表中列的值是在所有数据行均匀分布的,也就是说每种deptno值各有25万数据行与之对应。假设SQL搜索条件DEPTNO=10,利用deptno列上的索引进行数据搜索效率,往往不比全表扫描的高,ORACLE理所当然对索引“视而不见”,认为该索引的选择性不高。

但我们考虑另一种情况,如果一百万数据行实际不是在4种deptno值间平均分配,其中有99万行对应着值10,5000行对应值20,3000行对应值30,2000行对应值40。在这种数据分布图案中对除值为10外的其它deptno值搜索时,毫无疑问,如果索引能被应用,那么效率会高出很多。我们可以采用对该索引列进行单独分析,或用analyze语句对该列建立直方图,对该列搜集足够的统计数据,使Oracle在搜索选择性较高的值能用上索引。

第十,索引列值是否可为空(NULL)。如果索引列值可以是空值,在SQL语句中那些需要返回NULL值的操作,将不会用到索引,如COUNT(*),而是用全表扫描。这是因为索引中存储值不能为全空。

第十一,看是否有用到并行查询(PQO)。并行查询将不会用到索引。

第十二,看PL/SQL语句中是否有用到bind变量。由于数据库不知道bind变量具体是什么值,在做非相等连接时,如“<”,“>”,“like”等。Oracle将引用缺省值,在某些情况下会对执行计划造成影响。

如果从以上几个方面都查不出原因的话,我们只好用采用在语句中加hint的方式强制Oracle使用最优的“执行计划”。

hint采用注释的方式,有行注释和段注释两种方式。

如我们想要用到A表的IND_COL1索引的话,可采用以下方式:

“SELECT /*+ INDEX(A IND_COL1)*/ * FROM A WHERE COL1 = XXX;"

注意,注释符必须跟在SELECT之后,且注释中的“+”要紧跟着注释起始符“/*”或“--”,否则hint就被认为是一般注释,对PL/SQL语句的执行不产生任何影响。

两种有效的跟踪调试方法

Oracle提供了两种有效的工具来跟踪调试PL/SQL语句的执行计划。

一种是EXPLAIN TABLE方式。用户必须首先在自己的模式(SCHEMA)下,建立PLAN_TABLE表,执行计划的每一步骤都将记录在该表中,建表SQL脚本为在${ORACLE_HOME}/rdbms/admin/下的utlxplan.sql。

打开SQL*PLUS,输入“SET AUTOTRACE ON”,然后运行待调试的SQL语句。在给出查询结果后,Oracle将显示相应的“执行计划”,包括优化器类型、执行代价、连接方式、连接顺序、数据搜索路径以及相应的连续读、物理读等资源代价。

如果我们不能确定需要跟踪的具体SQL语句,比如某个应用使用一段时间后,响应速度忽然变慢。我们这时可以利用Oracle提供的另一个有力工具TKPROF,对应用的执行过程全程跟踪。

我们要先在系统视图V$SESSION中,可根据USERID或MACHINE,查出相应的SID和SERIAL#。

以SYS或其他有执行DBMS_SYSTEM程序包的用户连接数据库,执行:

EXECUTE DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(SID,SERIAL#,TRUE)

然后运行应用程序,这时在服务器端,数据库参数“USER_DUMP_DEST”指示的目录下,会生成ora__xxxx.trc文件,其中xxxx为被跟踪应用的操作系统进程号。

应用程序执行完成后,用命令tkprof对该文件进行分析。命令示例:“tkprof tracefile outputfile explain=userid/password"。在操作系统ORACLE用户下,键入“tkprof”,会有详细的命令帮助。分析后的输出文件outputfile中,有每一条PL/SQL语句的“执行计划”、CPU占用、物理读次数、逻辑读次数、执行时长等重要信息。你可以根据输出文件的信息,发现应用中究竟是哪条PL/SQL语句导致了问题的出现。

分享到:
评论

相关推荐

    为什么oracle有时不用索引来查找数据

    ### Oracle为何有时不使用索引来查找数据 Oracle数据库在处理SQL查询时,会根据一系列复杂的因素决定是否使用索引以及如何高效地检索数据。本文将深入探讨Oracle在哪些情况下可能会选择不使用索引的原因,并解释...

    为什么有时ORACLE数据库不用索引来查找数据.doc

    Oracle数据库在某些情况下选择不使用索引来查找数据,这一现象与数据库的优化器策略密切相关。Oracle数据库有两种主要的优化器:基于规则的优化器(RBO)和基于代价的优化器(CBO)。RBO遵循固定规则,而CBO自Oracle...

    Oracle 数据库查找替换工具

    6. **性能优化**:为了处理大量数据,工具可能会优化查询执行计划,如使用索引、并行处理等,提高查找和替换的速度。 7. **日志记录**:对于企业级应用,日志记录功能很重要,它可以追踪所有进行的操作,便于审计和...

    Oracle使用强制索引的方法与注意事项

    强制索引的使用需要谨慎,因为Oracle的查询优化器通常会根据数据量、索引统计信息和查询模式来决定最佳的执行计划。在某些情况下,当数据量较小或者查询条件能精确匹配索引时,索引可能更有效。但随着数据量的增加,...

    oracle数据库索引失效

    这是因为索引查找的成本在大量数据中变得更高。 其次,统计信息的过期或不准确也会导致索引失效。Oracle依赖于统计信息来决定最佳执行计划,如果这些信息不准确,优化器可能无法正确评估索引的价值。定期执行`...

    Oracle Index索引无效的原因与解决方法

    - **函数操作**:在索引列上直接使用函数,如`TO_CHAR`、`TO_DATE`等,会阻止索引的使用,因为数据库无法直接在索引中查找函数处理过的值。解决方法是创建函数索引,将函数应用到索引中。 - **隐式类型转换**:当...

    Oracle优化原则整理

    全表扫描会读取数据文件中的所有行,而索引查找只需要找到指定的行。如果必须进行全表扫描,考虑使用分区来降低影响。 4. **使用绑定变量**:绑定变量可以防止SQL语句硬解析,从而减少解析开销并提高执行计划的复用...

    索引内部原理.pdf

    Oracle数据库索引实现原理是数据库管理与优化的重要内容,理解这些原理可以帮助数据库管理员(DBA)更好地管理数据,提升查询效率,以及进行必要的维护操作。B-Tree是Oracle中最常用的索引类型,其核心是维护数据的...

    Oracle错误码大全

    在日常使用过程中,由于各种原因,我们可能会遇到各种错误,这些错误通常会以错误码的形式呈现,帮助开发者和管理员诊断问题。"Oracle错误码大全"就是这样一个宝贵的资源,它包含了6513个不同的错误码,几乎覆盖了...

    oracle获取汉字拼音和拼音首字母的功能函数

    Oracle Text可以通过索引和查询分析来处理汉字到拼音的转换,适用于大规模的数据处理。 6. **拼音首字母获取** 获取汉字的拼音首字母相对简单,因为大多数汉字的拼音首字母是固定的。可以创建一个映射表,存储每个...

    oracle实现多字段匹配一个关键字查询(本人亲测,没毛病)

    在Oracle数据库中,有时我们需要从多个字段中搜索包含特定关键字的数据。这种需求在很多场景下都非常常见,比如在CRM系统中搜索客户信息、在文档管理系统中查找文档等。本文将详细介绍如何利用Oracle SQL语句实现多...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    其三、职业方向多:Oracle数据库管理方向、Oracle开发及系统架构方向、Oracle数据建模数据仓库等方向。 四、 如何学习 认真听课、多思考问题、多动手操作、有问题一定要问、多参与讨论、多帮组同学 五、 体系结构 ...

    oracle常用的bug问题解决

    例如,当发现慢查询时,可以使用EXPLAIN PLAN分析查询路径,然后根据分析结果进行调整。 二、数据一致性bug 数据一致性问题通常表现为事务处理异常、回滚段错误或者并发控制问题。这类bug可能由于并发控制机制如...

    oracle生成拼音、五笔首字母的functions方法

    在Oracle数据库环境中,有时我们需要对汉字进行处理,例如生成拼音或五笔的首字母,这在数据检索、信息编码或构建搜索引擎时非常有用。本文将详细介绍如何在Oracle中实现这一功能,主要基于提供的两个SQL脚本文件:`...

    oracle学习及练习语句

    4. 查询与删除重复记录:在数据处理中,有时会出现重复的记录,这需要通过特定的SQL语句来处理。Oracle提供了`DISTINCT`关键字去除查询结果中的重复行,而在`删除重复记录sql.txt`中,你可能看到如何使用`GROUP BY`...

    Oracle中表的连接及其调整.

    Oracle 查询优化器会自动选择最适合的连接方法,但有时手动调整连接顺序或使用 hints 可以进一步优化性能。例如,在外连接查询中,驱动表通常选择那些需要返回所有记录的表,即使它们可能包含更多的数据。 总结来说...

    oracle+sql语句的性能调整_中文,来自oracle培训

    索引可以极大地加快数据查找的速度,但并非所有查询都适合创建索引。选择性高的列(即具有很多唯一值的列)和频繁用于查询条件的列是最理想的索引候选。同时,索引的维护也会带来额外的写操作开销,因此需要权衡利弊...

    oracle提取汉字拼音和首字母

    在Oracle数据库环境中,有时我们需要对汉字进行处理,例如获取汉字的拼音或首字母,这在中文数据检索、排序或建立索引时非常有用。本文将详细介绍如何使用PL/SQL存储过程来实现这一功能。 首先,我们需要理解Oracle...

    Oracle8i_9i数据库基础(DOC格式)

    - SQL优化:通过分析计划,使用索引,调整SQL语句来提升查询速度。 - 表分区:对大数据表进行分区,提高查询效率。 - 资源管理:设置资源限制,确保高优先级的会话得到足够的资源。 总的来说,《Oracle8i_9i数据库...

    Oracle官方文档CHM合集-Oracle10g错误代码

    2. **错误消息**:当错误发生时,数据库系统会显示的一段描述性文本,解释了错误的原因和可能的影响。 3. **解决方案**:官方文档会提供解决该错误的建议步骤,这可能包括修改SQL语句、检查配置设置或执行特定的...

Global site tag (gtag.js) - Google Analytics