非操作符



 网上有些地方说有关非的操作符不能利用索引,这些操作符有 !=<>!<!>NOT EXISTSNOT INNOT LIKE 。 下面来测试一下 !=<>!<!> NOT INNOT EXISTSNOT LIKE 会在其他文章中详细说明) 。

测试版本为 DB2 v8.1.0.64 ( 查看 DB2 版本 db2level)DB2 v9.7

1. 测试选择性不强的情况。

先创建测试数据 :

create table student
(
   
id int primary key not null ,
   
sid   int
)

: 定义主键时系统自动创建索引,如果 DROP 表,关于这个表的所有索引也被删除,也包括系统创建的索引。

create procedure insertDate()
BEGIN
     DECLARE v_id int;
     set v_id = 0;
     while v_id < 100000
     DO
       insert into student values(v_id,v_id );
       set v_id = v_id + 1;
     end while;
END
;

-- 插入数据

         call insertDate ()

-- 创建索引

         CREATE INDEX STU_SID ON STUDENT
   
( SID    ASC
   
)
    PCTFREE
10
    ALLOW REVERSE SCANS
;

注意 : 在一个表的数据大量修改后,要运行下面的命令:

RUNSTATS ON TABLE NBADV. STUDENT FOR INDEX  NBADV. STU_SID   SHRLEVEL REFERENCE

runstats on table nbadv . student with distribution and detailed indexes all

:NBADV. STUDENT [ 模式名 ].[ 表名 ] NBADV. STU_SID [ 模式名 ].[ 表名 ]

测试语句 :

select sid from student where sid <> 1 (!=<> 一样,就不测试了 )

 

select sid from student where sid !< 1

 



  

select sid from student where sid !> 100001

  

 

 

上面的语句都只能排除 10W 分之一,可以看到都没有利用索引。

 

2. 测试选择性强的情况。

 

  将上面的测试数据执行下面的修改

update student set sid = 1 where sid > 100 or sid = 0

注意 : 在一个表的数据大量修改后,要运行下面的命令:

RUNSTATS ON TABLE NBADV. STUDENT FOR INDEX  NBADV. STU_SID   SHRLEVEL REFERENCE

 

测试语句 :

select sid from student where sid <> 1 (!=<> 一样,就不测试了 )

 



 

select sid from student where sid !< 2

 



 select
sid from student where sid > 1 or sid < 1

 



 可以发现上面三个语句都利用了索引,但是 <> 利用索引后效率并没有高出多少,而 !< 利用索引后效率很高。将
select sid from student where sid <> 1 转化为 select sid from student where sid > 1 or sid < 1 后效率也是很高。我是这么理解的, <> 时将索引列上所有数据一个个取出来判断,然后取出不等于 1 的数据,这样索引列上每一个数据都要被取出判断,所以,效率很低。但是 !< 时,首先找到所以列上数据 2 的位置,然后将 2 之后的数据都取出来,由于查找 2 的位置很快,而取出数据也只有 100 个,所以,速度会很快。而 <1 and

>1 会查找 1 的开始位置和结束位置,然后取出开始位置之前和结束位置之后的数据,由于查找数据位置很快,而取出数据 也只有 100 行,所以速度很快。

   

下面测试 not in

10 万行数据中只有 100 不等于 1 的数据时:

select sid from student where sid   not in  (1)



 

 

select sid from student where sid > 1

 



  

10 万行数据中只有 99999 不等于 1 的数据时:

select sid from student where sid   not in  (1)

select sid from student where sid > 1

执行计划一样,如图:

 

 



 可以看到当条件的筛选性不强时, not in 和其他方式效率差不多,当数据筛选性很强时,就需要将 not in 转换成其他写法了。

 

总结 :

<> 虽和 not in 虽然能利用索引,但是利用索引后效率并不能改变多少,所以建议在数据筛选性很强时(满足条件的数据比较多),将 <> 转化为 < XX and >XX not in 也可以转化成别的。而 !< 或者 !> 可以利用索引,且索引利用后效率提升很多,不必转换。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值