zoukankan      html  css  js  c++  java
  • 让Oracle索引Null列

    1.建立环境

    create table t1 (id int,name varchar(10),age int);

    create table t2 (id int,name varchar(10),age int);

    insert into t1 values (1,’abc’,33);

    insert into t1 values (2,’’,31);

    insert into t2 values (1,’abc’,33);

    insert into t2 values (2,’’,31);

    insert into t1 values (3,’xyz’,34);

    2. Null的问题

    SQL> select * from t2 where name not in (select name from t1);

    no rows selected

    按照逻辑这里应该返回

    ID NAME AGE
    ————— ————— —————

    3 xyz 34

    解决方法

    select * from t2 where name not in (select nvl(name,0) from t1);

    select * from t2 where not exists (select name from t1 where t2.id=t1.id);

    select * from t2 where name not in (select name from t1 where t2.id=t1.id);

    注意这里这样写select * from t2 where not exists (select name from t1);也是不行的

    3其他-null建立到复合索引里边使null也可以走索引

    讲两个NULL与索引的小技巧

    3.1 既然NULL是可以进复合索引的,在我们需要对NULL进行索引时,就可以构造一个“伪复合索引”:

    CREATE INDEX my_index ON my_table(my_column,0);

    后面这个零就是加入的伪列。这样以后在有 my_column IS NULL 的条件就可以利用索引了(当然最终使用与否还得由CBO决定)。

    3.2 不想索引的行,即使不是NULL, 也可用函数把它剔除。

    假设有status_id列,里面有0:未处理,1:已处理 两种状态,我们关心的仅仅是0的行,处理完就会改成1. 这样表中0的行仅仅是少数,大部分是1的行,数据量多了BTREE索引的维护就有开销。

    这时可以建立这样的索引:

    CREATE INDEX my_index ON my_table(DECODE(status_id,0,0));

    它只对0行数据进行索引。当你要取未处理数据时,SELECT * FROM my_table WHERE DECODE(status_id,0,0)=0 就可以高效利用索引。

    以上测试根据 yangtingkun 发表于: 2011.05.19 23:46 的blog 《常数复合索引应用案例》进行的测试。

    —EOF—

    作者:Buro#79xxd 出处:http://www.cnblogs.com/buro79xxd/ 文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    UITextField的总结
    【实战】登录界面
    点分治学习
    2020/3/1
    2020/2/29
    2020/2/28
    2020/2/27
    2020/2/27
    最小树形图
    Ch’s gift HDU6162
  • 原文地址:https://www.cnblogs.com/buro79xxd/p/2537914.html
Copyright © 2011-2022 走看看