• Oracle初级索引学习总结


    前言

       索引是常见的数据库对象,建立索引的目的是为了提高记录的检索速度。它的设置好坏,使用是否得当,极大地影响数据库应用程序和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将只使用一个索引,至于使用那个索引,这个还要看情况而定。

    强制索引失效

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

    select Ename from EMP
    where ENo=7935
    and DNo=10
    and EType='A'

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

    select EName from EMP
    
    where ENo=7935
    
    and DNo+0=10   /*DNo上的索引将不会使用/*
    
    and EType|| ''='A'  /*EType上的索引将不会使用/*

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

    select * from DEPT
    
    where SAL*12>25000

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

    select * from DEPT
    
    where SAL>25000/12

    总结

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

  • 相关阅读:
    13.Query for Null or Missing Fields-官方文档摘录
    海南IT互联网招聘数据简单分析
    Mongo Spark Connector中的分区器(一)
    一、Golang中的反射基本使用
    Golang中的sync.Pool对象
    Golang中的内置函数
    golang单元测试简述
    Spark Streaming数据限流简述
    Golang中类面向对象特性
    在Docker中跑Hadoop与镜像制作
  • 原文地址:https://www.cnblogs.com/aehyok/p/3602340.html
Copyright © 2020-2023  润新知