前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Oracle初级索引学习总结

Oracle初级索引学习总结

作者头像
aehyok
发布2018-08-31 10:27:58
7490
发布2018-08-31 10:27:58
举报
文章被收录于专栏:技术博客技术博客

前言

   索引是常见的数据库对象,建立索引的目的是为了提高记录的检索速度。它的设置好坏,使用是否得当,极大地影响数据库应用程序和Database的性能。虽然有许多资料讲索引的用法,DBA和Developer们也经常与它打交道,但还是有不少的人对它存在误解,比如我本人就不是很清楚这其中的道理。所以特此进行总结,也请大牛们来给检查检查,分享下你们的经验。

什么情况下会使用到索引

  一般来说,对于单列索引,只要Select、Delete、Update语句的Where条件中有此列,就会使用此索引。

  对于多列索引,假如一个表中的主键(ID,Name,Age三个字段联合索引),只有当Where条件中包含索引中的前一个或几个列时才会用到索引。

  如ID条件,ID、Age组合条件,ID、Name、Age组合条件,而仅有Name、Age条件,没有ID条件是不会使用索引的。因为此索引是先根据ID排序,ID相同的再根据Name排序,ID、Name相同的再根据Age排序。

 什么情况下应该为表建立索引

  一般来说,满足下列条件的应该建立索引:

  1、列经常被用在Where条件中或连接条件中

  2、列的数据比较分散,即重复值不多

  3、列包含大量的空值

  4、几个列经常一起用在Where条件或连接条件中(联合索引)

  5、大部分的检索只返回大表中的小部分记录(2%~5%)

什么情况下不应该为表建立索引

  不应该建立索引的情况有:

  1、表的数据量不大

  2、列很少用在查询条件中

  3、大部分的检索都返回大量的数据  

  4、表的Update操作很频繁

但索引并非总是最佳选择,如果发现Oracle在有索引的情况下,没有使用索引,这并不是优化器出错。在有些情况下,Oracle确实会选择全表扫描(Full Table Scan),而非索引扫描(Index Scan)。这些情况通常有:   1、表未做统计,或者统计陈旧,导致Oracle判断失误。   2、根据该表拥有的记录数和数据块数,实际上全表扫描要比索引扫描更快。

但是,Oracle是否真正使用索引,使用索引是否真正有效,还是必须进行实地的测验。合理的做法是,对缩写的复杂sql,在将它写入应用程序之前,先在产品数据库上做一次执行计划(explain)。explain会获得Oracle对该sql的解析(plan),可以明确地看到Oracle是如何优化该sql的。

如果经常做explain,就会发现,喜爱写发扎的sql并不是好习惯,因为过分复杂的sql其解析计划往往不尽如人意。事实上,如果库表结构设计的合理,一般情况下我们很少需要写复杂的sql。将复杂的Sql拆开,有时候会极大地提高效率,因为能获得很好的优化。

用索引提高效率

   通常情况下,通过索引查询数据比全表扫描要快。同样在联结多个表时使用索引也可以提高效率。另一个使用索引的好处是,它提供了主键(primary key)的唯一性验证。不过使用索引时也必须注意到它的代价。索引需要空间来存储,也需要定期维护,每当有记录在表中增减或索引列被修改时,索引本身也会被修改。这意味着每条记录的Insert、Delete、Update将为此多付出4、5此的磁盘I/O。因为索引需要额外的存储空间和处理,那些不必要的索引反而会使查询反应时间变慢。

  Oracle对索引有两种访问模式:

  索引唯一扫描(Index Unique Scan)

  索引范围查询(Index Range Scan)

  适用于两种情况:1、基于一个范围的检索  2、基于非唯一性索引的检索

  当where子句中有多个索引列,且包含非“=”号时,Oracle会放弃使用非“=”号的索引

  当where子句中有多个索引列,且都为非“=”号时,Oracle将只使用一个索引,至于使用那个索引,这个还要看情况而定。

强制索引失效

   如果两个或以上具有相同的等级,而我们只想使用其中的一个(通过它,检索出的记录数量少),我们可以使用下面的方法:

代码语言:javascript
复制
select Ename from EMP
where ENo=7935
and DNo=10
and EType='A'

如果我们只想用到ENo上的索引(相对另外两个条件记录数量很少,做合并不划算)则可改编为:

代码语言:javascript
复制
select EName from EMP

where ENo=7935

and DNo+0=10   /*DNo上的索引将不会使用/*

and EType|| ''='A'  /*EType上的索引将不会使用/*

同样,如果我们想使用某个列上的索引,则不能对此列做运算。

代码语言:javascript
复制
select * from DEPT

where SAL*12>25000

不能使用SAL列上的索引,可改编为:

代码语言:javascript
复制
select * from DEPT

where SAL>25000/12

总结

   对Oracle的索引了解还不是很深入,只是浮于表面的认识,日后要多加使用研究。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2014-03-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档