今天研究了一下oracle对部分记录建立索引的方法。其实对部分记录建立的索引就是基于
函数的索引。由于部分记录函数化以后,返回了NULL值,而ORACLE索引不索引NULL值,
导致这些记录没有索引条目。
  
  这样我们就可以对自已关注的少数记录建立很小索引,提高查询速度。
一个例子,学校有10000学生,其中女同学仅有100人。我们经常关注女生,几乎不关注男生。
这样我们就可以只在女生记录上添加索引。这个很小的索引就能帮我们很快把女生找到。
做个测试:
SQL> create table students(id int ,name varchar2(200),sex varchar(16)) 
    2    / 
Table created

SQL> declare 
    2     style varchar2(16); 
    3    begin 
    4    for i in 1..10000 loop 
    5     if(i mod 100 = 0) then 
    6         style:='F'; 
    7     else style := 'M'; 
    8     end if; 
    9     insert into students values(i,rpad('student'||i,150,'F'),style); 
10     end loop; 
11     commit; 
12    end; 
13    / 
PL/SQL procedure successfully completed.

这里为了让女生分布均匀,加了i mod 100;
SQL> select count(1) from students where sex='F'
  2  /
 
  COUNT(1)
----------
       100
刚好100位女生.
SQL> select * from students where (case when sex='F' then sex end)='F' 
    2    / 
已选择100行。 
执行计划 
---------------------------------------------------------- 
Plan hash value: 4078133427 
------------------------------------------------------------------------------ 
| Id    | Operation                 | Name         | Rows    | Bytes | Cost (%CPU)| Time         | 
------------------------------------------------------------------------------ 
|     0 | SELECT STATEMENT    |                    |        93 | 11625 |        56     (2)| 00:00:01 | 
|*    1 |    TABLE ACCESS FULL| STUDENTS |        93 | 11625 |        56     (2)| 00:00:01 | 
------------------------------------------------------------------------------ 
Predicate Information (identified by operation id): 
--------------------------------------------------- 
     1 - filter(CASE "SEX" WHEN 'F' THEN "SEX" END ='F') 
Note 
----- 
     - dynamic sampling used for this statement

统计信息 
---------------------------------------------------------- 
                169    recursive calls 
                    0    db block gets 
                337    consistent gets 
                    0    physical reads 
                    0    redo size 
            17196    bytes sent via SQL*Net to client 
                451    bytes received via SQL*Net from client 
                    8    SQL*Net roundtrips to/from client 
                    4    sorts (memory) 
                    0    sorts (disk) 
                100    rows processed

执行计划采用了全表扫描。
建立部分元组索引:

SQL> create index femaleIndex on students(case when sex='F' then sex end); 
Index created 
SQL> exec dbms_stats.gather_index_stats('study','femaleIndex') 
    
PL/SQL procedure successfully completed 
    
SQL> select num_rows,blevel from user_indexes where index_name=upper('femaleIndex') 
    2    / 
    
    NUM_ROWS         BLEVEL 
---------- ---------- 
             100                    0 

索引条目刚好100个,与女生数相等。

SQL> select * from students where (case when sex='F' then sex end)='F' 
    2    / 
已选择100行。

执行计划 
---------------------------------------------------------- 
Plan hash value: 2152294204 
| Id    | Operation    | Name                | Rows    | Bytes | Cost (%CPU)| Time | 
------------------------------------------------------------------------------- 
|    0 | SELECT STATEMENT                        |                    | 93 | 11625 |    2     (0)|00:00:01 | 
|    1 |    TABLE ACCESS BY INDEX ROWID| STUDENTS | 93 | 11625 |    2     (0)| 00:00:01 | 
|* 2 |     INDEX RANGE SCAN                    | FEMALEINDEX| 38 |         |    1     (0)| 00:00:01 | 
-------------------------------------------------------------------------------- 
Predicate Information (identified by operation id): 
--------------------------------------------------- 
     2 - access(CASE "SEX" WHEN 'F' THEN "SEX" END ='F') 
Note 
------ dynamic sampling used for this statement

统计信息 
---------------------------------------------------------- 
                 11    recursive calls 
                    0    db block gets 
                174    consistent gets 
                    0    physical reads 
                    0    redo size 
            17196    bytes sent via SQL*Net to client 
                451    bytes received via SQL*Net from client 
                    8    SQL*Net roundtrips to/from client 
                    0    sorts (memory) 
                    0    sorts (disk) 
                100    rows processed

可以看到速度提高了很多。但是如果我们查询男生:

SQL> select * from students where (case when sex='F' then sex end)='M' 
    2    / 
未选定行

执行计划 
---------------------------------------------------------- 
Plan hash value: 2152294204 
------------------------------------------------------------------------------- 
| Id    | Operation | Name                | Rows    | Bytes | Cost (%CPU)|Time         | 
-------------------------------------------------------------------------------- 
|     0 | SELECT STATEMENT                |                    |         3 | 375 | 2     (0)|00:00:01 | 
|     1 |    TABLE ACCESS BY INDEX ROWID| STUDENTS|    3 | 375 | 2     (0)|00:00:01 | 
|*    2 |     INDEX RANGE SCAN            | FEMALEINDEX |    38 |        |    1     (0)|00:00:01 | 
-------------------------------------------------------------------------------- 
Predicate Information (identified by operation id): 
--------------------------------------------------- 
     2 - access(CASE "SEX" WHEN 'F' THEN "SEX" END ='M') 
Note 
----- 
     - dynamic sampling used for this statement

统计信息 
---------------------------------------------------------- 
                 11    recursive calls 
                    0    db block gets 
                 67    consistent gets 
                    0    physical reads 
                    0    redo size 
                375    bytes sent via SQL*Net to client 
                374    bytes received via SQL*Net from client 
                    1    SQL*Net roundtrips to/from client 
                    0    sorts (memory) 
                    0    sorts (disk) 
                    0    rows processed

居然没有记录返回!! 当然了因为(case when sex='F' then sex end)这个函数,我们姑且把它看成一个函数,是不会返回'M'这个值的。这也说明了如果建立了函数索引,查询条件上使用了该函数,则查询必走此索引。
以上是个简单的例子,假如我们一个项目管理系统,项目只有三种状态:投标,开发,验收。历经很多年,验收的验目很多,但正在投标,开发的项目肯定不多(IBM可能有很多),这样我们就可以只在需要关注的投标与开发的记录上添加索引:
create index test on projects(case when status='投标' then  status when status='开发' then  status end).
部分记录建立的索引还有一个经典用法就是建立唯一索引,完成对记录的约束,比如上面的例子,如果建成唯一索引,那么全校只能有一个女生了,而男生无限制。我不喜欢这样,所以就不演示了,记得加个unique就成。
本文转自 anranran 51CTO博客,原文链接:http://blog.51cto.com/guojuanjun/325580

oracle仅部分记录建立索引的方法相关推荐

  1. win10系统哪个是索引服务器,小编教你在Win10系统下建立索引的方法技巧

    在使用电脑的过程中,有时候为了快速找到某个文件或程序,我们会通过搜索功能来实现,不过大家也知道搜索一功能默认全盘扫描,若是用户的电脑配置不高的话那搜索速度就比较慢了,所以我们可以搜索时可以建立索引条目 ...

  2. Oracle找出需要建立索引的表

    文章讨论的是本来应该建立索引而因为疏忽,或者考虑不周全而没有建立的情况 select distinct sp.OBJECT_NAME,round(ds.bytes/1024/1024,2) MB,nu ...

  3. oracle的索引使用方法,在OracleE数据库的字段上建立索引的方法

    当where子句对某一列使用函数时,除非利用这个简单的技术强制索引,否则Oracle优化器不能在查询中使用索引. 通常情况下,如果在WHERE子句中不使用诸如UPPER.REPLACE 或SUBSTR ...

  4. 搜索引擎索引之如何建立索引

                                              本文节选自<这就是搜索引擎:核心技术详解>第三章 3.4建立索引 正如前述章节所述,索引结构如果建立好了 ...

  5. ORACLE索引重建方法与索引的三种状态

    一.重建索引的前提 1.表上频繁发生update,delete操作: 2.表上发生了alter table ..move操作(move操作导致了rowid变化). 二.重建索引的标准 1.索引重建是否 ...

  6. 创建索引oracle 很慢,Oracle 建立索引及SQL优化

    复合索引用户可以在多个列上建立索引,这种索引叫做复合索引(组合索引).复合索引的创建方法与创建单一索引的方法完全一样.但复合索引在数据库操作期间所需的开销更小,可以代替多个单一索引. 如何某表的某个字 ...

  7. oracle不适合建立索引的场景,Oracle 分区表中本地索引和全局索引的适用场景

    背景 分区表创建好了之后,如果需要最大化分区表的性能就需要结合索引的使用,分区表有两种索引:本地索引和全局索引.既然存在着两种的索引类型,相信存在即合理.既然存在就会有存在的原因,也就是在特定的场景中 ...

  8. 用oracle建立索引步骤,Oracle建立全文索引的步骤

    Oracle全文索引相信大家都有一定的了解,下面就教您如何建立oracle全文索引,如果您对oracle全文索引方面感兴趣的话,不妨一看. 步骤一 检查和设置数据库角色 首先检查数据库中是否有CTXS ...

  9. oracle表重命名 索引,CSS_在Oracle数据库中按用户名重建索引的方法,如果你管理的Oracle数据库下某 - phpStudy...

    在Oracle数据库中按用户名重建索引的方法 如果你管理的Oracle数据库下某些应用项目有大量的修改删除操作, 数据索引是需要周期性的重建的. 它不仅可以提高查询性能, 还能增加索引表空间空闲空间大 ...

最新文章

  1. c语言课程设计学生籍贯信息记录簿,C语言课程设计 学生籍贯信息记录簿设计.doc...
  2. 使用command-privilege给H3C、华为设备的用户帐号授权
  3. Python(Dict和Set类型)
  4. SpringBoot 路径处理
  5. 无监督学习 k-means_无监督学习-第1部分
  6. 百度地图批量转换 GPS坐标转百度地图坐标 问题
  7. 2020华为软件精英挑战赛-有向图找环
  8. chrome如何调试html,如何用firefox或chrome浏览器调试js和jquery程序
  9. Linux paste命令
  10. matlab:图像的余弦变换(DCT)
  11. 目前微型计算机硬件主要采用,目前使用的微型计算机硬件主要采用的电子器件是()。 A. 真空管 B. 晶体管 C. 大规模和超大规模集成电路...
  12. 集成运算放大器对输入级的要求
  13. Variational Autoencoders and Nonlinear ICA: A Unifying Framework
  14. js中事件绑定3种方法以及事件委托
  15. win10无法识别光驱的解决方法
  16. 解决问题:The server time zone value ‘�й���׼ʱ��‘ is unrecognized or represents more than one time zone.
  17. 严蔚敏《数据结构》——导航
  18. Linux命令总结-cd
  19. 程序员的自我修炼(一):打通任督二脉
  20. 深圳见!本周五,GIAC全球互联网架构大会强势来袭!

热门文章

  1. 打包巨慢怎么办?这些工具让你爱不释手
  2. 如何提高Eclipse的运行速度 之总结
  3. 【Hive】Hive的数据类型
  4. java.lang unsupported classversion解决方法
  5. Unity点击播放卡死问题的解决
  6. 错误:invalid_client没有应用程序名称
  7. Normalize.css和Reset CSS有什么区别?
  8. 标签空间而不是多个不间断的空格(“nbsp”)?
  9. android中搜索对话框,android – 如何使用onSearchRequested()调用搜索对话框
  10. JAVA:Eclipse代码和xml文件的智能提示