• 复合索引,不走索引情况


    一般情况,查询中需要有复合索引的前导列,才会使用复合索引

    3.1)INDEX SKIP SCAN(复合索引之索引跳跃扫描)
        Oracle 9i后提供,有时候复合索引的前导列(索引包含的第一列)没有在查询语句中出现,oralce也会使用该复合索引,
    这时候就使用的INDEX SKIP SCAN;
    3.2)什么时候会触发 INDEX SKIP SCAN
    前提条件:表有一个复合索引,且在查询时有除了前导列(索引中第一列)外的其他列作为条件,并且优化器模式为CBO时当Oracle发现前导列的唯一值个数很少时,会将每个唯一值都作为常规扫描的入口,在此基础上做一次查找,最后合并这些查询;
    例如:
        假设表emp有ename(雇员名称)、job(职位名)、sex(性别)三个字段,并且建立了如 create index idx_emp on emp (sex, ename, job) 的复合索引;因为性别只有 '男' 和 '女' 两个值,所以为了提高索引的利用率,Oracle可将这个复合索引拆成 ('男', ename, job),('女', ename, job)这两个复合索引;当查询 select * from emp where job = 'Programmer' 时该查询发出后:    Oracle先进入sex为'男'的入口,这时候使用到了 ('男', ename, job) 这条复合索引,查找 job = 'Programmer' 的条目;再进入sex为'女'的入口,这时候使用到了 ('女', ename, job) 这条复合索引,查找 job = 'Programmer' 的条目;最后合并查询到的来自两个入口的结果集。

    不走索引的原因,大概有如下8种:
    1)建立组合索引,但查询谓词并未使用组合索引的第一列,此处有一个INDEX SKIP SCAN概念。
    2)在包含有null值的table列上建立索引,当时使用select count(*) from table时不会使用索引。
    3)在索引列上使用函数时不会使用索引,如果一定要使用索引只能建立函数索引。
    如:Where条件中对字段增加处理函数将不使用该列的索引
    select * from emp where to_char(hire_date,'yyyymmdd')='20080411' (不使用)
    select * from emp where hire_date = to_char('20080411','yyyymmdd') (使用)
    4)当被索引的列进行隐式的类型转换时不会使用索引。

    示例1:

    select * from t where indexed_column = 5,而indexed_column列建立索引但类型是字符型,这时Oracle会产生隐式的类型转换,转换后的语句类似于select * from t where to_number(indexed_column) = 5,此时不走索引的情况类似于case3

    示例2:日期转换也有类似问题
    select * from t where trunc(date_col) = trunc(sysdate)其中date_col为索引列,这样写不会走索引,可改写成select * from t where date_col >= trunc(sysdate) and date_col < trunc(sysdate+1),此查询会走索引。
    5)并不是所有情况使用索引都会加快查询速度,full scan table 有时会更快,尤其是当查询的数据量占整个表的比重较大时,因为full scan table采用的是多块读,
    当Oracle优化器没有选择使用索引时不要立即强制使用,要充分证明使用索引确实查询更快时再使用强制索引。
    6)<>
    7)like’%dd’百分号在前
    8)not in ,not exist

  • 相关阅读:
    Download~!
    单身一百年也没用
    文件包含
    重温Bootstrap
    静态网页与动态网页的理解
    百度检索小技巧
    关于网络学习中易混淆知识点的辨析
    常见的网站功能需求及解决方案
    <textarea>输入框提示文字
    利用JavaScript函数对字符串进行加密
  • 原文地址:https://www.cnblogs.com/houxt/p/12721287.html
Copyright © 2020-2023  润新知