`
楚若之夜
  • 浏览: 125040 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

Oracle 索引相关理论知识

 
阅读更多

 

(一)   建立索引常用的规则如下:

1)         表的主键、外键必须有索引;

2)         数据量超过300的表应该有索引;

3)         经常与其他表进行连接的表,在连接字段上应该建立索引;

4)         经常出现在Where子句中的字段,特别是大表的字段,应该建立索引;

5)         索引应该建在选择性高的字段上;

6)         索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引;

7)         复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替:

a)         正确选择复合索引中的主列字段,一般是选择性较好的字段;

b)         复合索引的几个字段是否经常同时以AND方式出现在Where子句中?单字段查询是否极少甚至没有?如果是,则可以建立复合索引;否则考虑单字段索引;

c)         如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;

d)         如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;

e)         如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;

8)         频繁进行数据操作的表,不要建立太多的索引;

9)         删除无用的索引,避免对执行计划造成负面影响;

 

以上是一些普遍的建立索引时的判断依据。一言以蔽之,索引的建立必须慎重,对每个索引的必要性都应该经过仔细分析,要有建立的依据。因为太多的索引与不充分、不正确的索引对性能都毫无益处:在表上建立的每个索引都会增加存储开销,索引对于插入、删除、更新操作也会增加处理上的开销。 另外,过多的复合索引,在有单字段索引的情况下,一般都是没有存在价值的;相反,还会降低数据增加删除时的性能,特别是对频繁更新的表来说,负面影响更大。

 

(二)   避免对列的操作:

1)         任何对列的操作都可能导致全表扫描,这里所谓的操作包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等式的右边,甚至去掉函数。

1:下列SQL条件语句中的列都建有恰当的索引,但30万行数据情况下执行速度却非常慢:

select * from record where  substrb(CardNo,1,4)='5378'(13)

select * from record where  amount/30< 100011秒)

select * from record where  to_char(ActionTime,'yyyymmdd')='19991201'10秒)

由于where子句中对列的任何操作结果都是在SQL运行时逐行计算得到的,因此它不得不进行表扫描,而没有使用该列上面的索引;如果这些结果在查询编译时就能得到,那么就可以被SQL优化器优化,使用索引,避免表扫描,因此将SQL重写如下:

select * from record where CardNo like  '5378%'< 1秒)

select * from record where amount  < 1000*30< 1秒)

select * from record where ActionTime= to_date ('19991201' ,'yyyymmdd')< 1秒)

 

(三)   避免不必要的类型转换:

1)         尽量避免潜在的数据类型转换。如将字符型数据与数值型数据比较,ORACLE会自动将字符型用to_number()函数进行转换,从而导致全表扫描。

2tab1中的列col1是字符型(char),则以下语句存在类型转换:

select col1,col2 from tab1 where col1>10;

应该写为: select col1,col2 from tab1 where col1>'10'

(四)   增加查询的范围限制

1)         增加查询的范围限制,避免全范围的搜索

3:以下查询表record 中时间ActionTime小于200131日的数据

select * from record where ActionTime < to_date ('20010301' ,'yyyymm')

查询计划表明,上面的查询对表进行全表扫描,如果我们知道表中的最早的数据为200111日,那么,可以增加一个最小时间,使查询在一个完整的范围之内:

select * from record where ActionTime < to_date ('20010301' ,'yyyymm') and   ActionTime > to_date ('20010101' ,'yyyymm')

后一种SQL语句将利用上ActionTime字段上的索引,从而提高查询效率。把'20010301'换成一个变量,根据取值的机率,可以有一半以上的机会提高效率。同理,对于大于某个值的查询,如果知道当前可能的最大值,也可以在Where子句中加上 “AND 列名< MAX(最大值)”

(五)   尽量去掉"IN""OR"

1)         含有"IN""OR"Where子句常会使用工作表,使索引失效;如果不产生大量重复值,可以考虑把子句拆开;拆开的子句中应该包含索引。

4select count(*) from stuff where id_no in('0','1')23秒)

可以考虑将or子句分开:

select count(*) from stuff where id_no='0'  

select count(*) from stuff where id_no='1'

然后再做一个简单的加法,与原来的SQL语句相比,查询速度更快

(六)   尽量去掉 "<>"

1)         尽量去掉 "<>",避免全表扫描,如果数据是枚举值,且取值范围固定,则修改为"OR"方式

5UPDATE SERVICEINFO SET STATE=0 WHERE STATE<>0;

以上语句由于其中包含了"<>",执行计划中用了全表扫描(TABLE ACCESS FULL),没有用到state字段上的索引。实际应用中,由于业务逻辑的限制,字段state为枚举值,只能等于012,而且,值等于=12的很少,因此可以去掉"<>",利用索引来提高效率。

修改为:UPDATE SERVICEINFO SET STATE=0  WHERE STATE = 1 OR STATE = 2 。进一步的修改可以参考第4种方法

(七)   去掉Where子句中的IS NULLIS NOT NULL

1)         Where字句中的IS NULLIS NOT NULL将不会使用索引而是进行全表搜索,因此需要通过改变查询方式,分情况讨论等方法,去掉Where子句中的IS NULLIS NOT NULL

(八)   索引提高数据分布不均匀时查询效率

1)         索引的选择性低,但数据的值分布差异很大时,仍然可以利用索引提高效率。

A、数据分布不均匀的特殊情况下,选择性不高的索引也要创建。

ServiceInfo中数据量很大,假设有一百万行,其中有一个字段DisposalCourseFlag,取值范围为枚举值:[01234567]。按照前面说的索引建立的规则,选择性不高的字段不应该建立索引,该字段只有8种取值,索引值的重复率很高,索引选择性明显很低,因此不建索引。然而,由于该字段上数据值的分布情况非常特殊,具体如下表:

取值范围                   1~5        6        7
占总数据量的百分比        1%        98%        1%

而且,常用的查询中,查询DisposalCourseFlag<6 的情况既多又频繁,毫无疑问,如果能够建立索引,并且被应用,那么将大大提高这种情况的查询效率。因此,我们需要在该字段上建立索引。

(九)   like子句尽量前端匹配

1)         因为like参数使用的非常频繁,因此如果能够对like子句使用索引,将很高的提高查询的效率。

6select * from city where name like ‘%S%’

以上查询的执行计划用了全表扫描(TABLE ACCESS FULL),如果能够修改为:

select * from city where name like ‘S%’

那么查询的执行计划将会变成(INDEX RANGE SCAN),成功的利用了name字段的索引。这意味着Oracle SQL优化器会识别出用于索引的like子句,只要该查询的匹配端是具体值。因此我们在做like查询时,应该尽量使查询的匹配端是具体值,即使用like ‘S%’

(十)   Case语句合并多重扫描

1)         我们常常必须基于多组数据表计算不同的聚集。例如下例通过三个独立查询:

81select count(*) from emp where sal<1000;

2select count(*) from emp where sal between 1000 and 5000;

3select count(*) from emp where sal>5000;

这样我们需要进行三次全表查询,但是如果我们使用case语句:

select
count (sale when sal <1000
then 1 else null end)                count_poor,
count (sale when between 1000 and 5000
then 1 else null end)                count_blue_collar,
count (sale when sal >5000
then 1 else null end)                count_poor
from emp;
这样查询的结果一样,但是执行计划只进行了一次全表查询。

(十一)         使用基于函数的索引

1)         select * from emp where substr(ename,1,2)=’SM’;

可以创建一个带有substr函数的基于函数的索引:

create index emp_ename_substr on eemp ( substr(ename,1,2) );

这样在执行上面的查询语句时,这个基于函数的索引将排上用场,执行计划将是(INDEX RANGE SCAN)。

(十二)         基于函数的索引要求等式匹配

1)         创建了基于函数的索引,但是如果执行下面的查询:

select * from emp where substr(ename,1,1)=’S’

得到的执行计划将还是(TABLE ACCESS FULL),因为只有当数据列能够等式匹配时,基于函数的索引才能生效,这样对于这种索引的计划和维护的要求都很高。请注意,向表中添加索引是非常危险的操作,因为这将导致许多查询执行计划的变更。然而,如果我们使用基于函数的索引就不会产生这样的问题,因为Oracle只有在查询使用了匹配的内置函数时才会使用这种类型的索引。

(十三)         决定使用全表扫描还是使用索引

1)         在大多数情况下,全表扫描可能会导致更多的物理磁盘输入输出,但是全表扫描有时又可能会因为高度并行化的存在而执行的更快。如果查询的表完全没有顺序,那么一个要返回记录数小于10%的查询可能会读取表中大部分的数据块,这样使用索引会使查询效率提高很多。但是如果表非常有顺序,那么如果查询的记录数大于40%时,可能使用全表扫描更快。因此,有一个索引范围扫描的总体原则是:

a)         对于原始排序的表  仅读取少于表记录数40%的查询应该使用索引范围扫描。反之,读取记录数目多于表记录数的40%的查询应该使用全表扫描。

b)        对于未排序的表    仅读取少于表记录数7%的查询应该使用索引范围扫描。反之,读取记录数目多于表记录数的7%的查询应该使用全表扫描。

 

随着时间的推移和数据的累计与变化,ORACLESQL语句的执行计划也会改变,比如:基于代价的优化方法,随着数据量的增大,优化器可能错误的不选择索引而采用全表扫描。这种情况可能是因为统计信息已经过时,在数据量变化很大后没有及时分析表;但如果对表进行分析之后,仍然没有用上合理的索引,那么就有必要对SQL语句用HINT提示,强制用合理的索引。但这种HINT提示也不能滥用,因为这种方法过于复杂,缺乏通用性和应变能力,同时也增加了维护上的代价;相对来说,基于函数右移、去掉“IN OR <>IS NOT NULL ”、分解复杂的SQL语句等等方法,却是放之四海皆准的,可以放心大胆的使用。

分享到:
评论

相关推荐

    oracle数据库基础知识

    Oracle数据库基础知识是每个IT从业者或自学者必备的知识领域。以下将深入讲解Oracle数据库的一些关键概念和操作。 一、Oracle数据库系统概述 Oracle数据库系统由Oracle公司开发,提供了一整套解决方案,包括数据库...

    ORACLE索引与高性能SQL介绍

    这不仅涉及到理论知识的学习,更需要在实践中不断探索和总结,才能达到真正的精通。在日常工作中,持续关注Oracle官方文档和技术社区的最新动态,结合实际业务需求进行调整和优化,是提升数据库性能不可或缺的一环。

    ORACLE的理论知识1.ppt

    Oracle数据库是一种广泛使用的大型关系型数据库管理系统,其理论知识涵盖了多个方面。以下是对标题和描述中涉及的Oracle数据库体系结构的详细解释。 1. **Oracle的物理结构**: - **数据文件(Datafiles)**: 存储...

    Oracle资料相关

    5. **Oracle学习资料**: 学习Oracle不仅需要理论知识,实践操作同样重要。通过阅读压缩包中的“Oracle学习资料”,可以深入了解Oracle的工作原理,学习如何进行数据库的日常运维,掌握性能优化技巧,以及如何处理...

    oracle学习总结(适合刚学习oracle的人)

    Oracle数据库是全球广泛..."要打印的文件"可能是学习资料或练习脚本,对于初学者来说,通过实践操作和案例分析,将理论知识应用于实际,是快速掌握Oracle的不二法门。希望这些信息能为初学者提供一个良好的学习起点。

    oracle索引介绍

    为了解释上述理论知识,我们可以参考以下实例: - **创建索引**: ```sql SQL&gt; create index indx_t on t(object_type, object_name); ``` 这里我们创建了一个基于`object_type`和`object_name`两个列的组合...

    Oracle 9i 索引管理秘密,顶级专家谈索引管理技巧

    《Oracle 索引管理秘密,顶级专家谈索引管理技巧》这本书汇集了Oracle领域内多位顶级专家的经验与智慧,不仅深入浅出地讲解了索引管理的基础知识,还提供了大量实用的操作指南和最佳实践案例。无论是对于初学者还是...

    oracle 知识库 (整理的chm文档)

    虽然这些知识来源于2004年的资源,但Oracle的基本原理和最佳实践并未发生根本变化。因此,对于初学者和经验丰富的数据库管理员来说,这些内容仍然是宝贵的参考资料。通过深入学习和实践,你可以更好地理解和运用...

    oracle相关教程知识点

    总的来说,Oracle教程提供了丰富的Oracle数据库系统知识,从基础知识到高级应用,从理论到实践,都进行了详尽的阐释。通过这份教程,读者不仅能够掌握Oracle数据库的操作技能,还能理解Oracle在云计算时代的重要战略...

    Oracle知识库(教程)

    Oracle知识库是一个全面涵盖Oracle数据库管理系统相关知识的资源集合,主要针对希望学习和掌握Oracle技术的用户。这个中文版的教程以CHM(Compiled Help Manual)格式提供,方便用户在无需互联网连接的情况下离线...

    Oracle相关的题目及答案

    Oracle是世界上最广泛使用的数据库管理系统之一,它在企业级...通过深入学习和实践这些知识点,你可以逐步提高自己在Oracle领域的专业水平,无论是在面试中应对相关问题,还是在实际工作中解决问题,都能更加得心应手。

    索引对Oracle Database优化的探讨.pdf

    【Oracle 数据库优化:索引的重要性】 在Oracle Database中,索引是一种关键的数据库结构,其目的...然而,这也需要数据库管理员具备深厚的索引理论知识和实践经验,以做出正确的决策,确保索引策略的高效性和适应性。

    ORACLE数据库理论及应用.ppt

    Oracle数据库理论及应用涵盖了Oracle数据库的基础架构、数据模型、数据存储、数据查询、数据安全、性能优化等方面的知识。 Oracle数据库的基础架构包括实例、数据库、表空间、段、-extents、数据块等概念。 ...

    Oracle课程相关练习oracle-job-master.zip

    "oracle-job-master"这个文件名可能指的是与Oracle数据库管理和维护相关的作业或任务,可能包含练习题目、解答示例、实战项目等,旨在帮助学习者将理论知识应用于实际操作中,提高动手能力。通过这些练习,学习者...

    Oracle学习相关资料大全

    "oracle电子书"和"课程相关PDF、PPT、WORD等文件资料"涵盖了各种教材和课程材料,它们可能是详细的教程、案例研究或者实战项目,帮助你巩固理论知识并提升实践能力。PPT文件可能包含清晰的图表和流程图,帮助理解和...

    Oracle知识库,手册

    这份"Oracle知识库,手册"集合提供了全面的Oracle学习和参考资源,特别适合DBA(数据库管理员)、开发人员以及对Oracle系统感兴趣的任何人。CHM版的手册意味着这些资料是以Windows帮助文件的格式存在,便于离线查阅...

    Oracle培训相关练习

    Oracle是全球知名的数据库管理系统,广泛应用于企业级的数据存储与管理。...在学习过程中,不仅要关注理论知识,还要注重动手实践,模拟真实环境解决问题,这样才能真正提高在Oracle数据库管理方面的技能。

    oracle实践精华知识集

    《Oracle实践精华知识集》包含了过去三个月对Oracle数据库系统深入学习的丰富内容,涵盖了理论、实践、技巧和参考资料。此集合旨在为初学者提供全面的学习路径,帮助他们掌握Oracle的核心概念和技术。 首先,...

    oracle基础知识回顾与练习.zip

    学习Oracle不应止步于基础,随着经验的积累,你可能需要深入学习数据库设计理论、性能调优技巧、分布式数据库、物化视图、数据库链接等高级主题。同时,Oracle官方文档和社区资源(如Oracle技术网、Stack Overflow...

Global site tag (gtag.js) - Google Analytics