在开始测试前先创建测试数据:
create table student
(
id int primary key not null ,
sid int
)
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 ()
在这里,我首先创建了一个表,其中 id 为主键。注意 DB2 中默认将主键列创建为索引,所以在这个表中 id 列有索引, sid 列没有索引。之后插入了 10 万行的数据。下面测试 or 和 and 一边有索引时一边没索引时的情况
select * from student where sid = 5 or id = 10
select * from student where sid = 5 and id = 10
可以看到当 or 的一边有索引一边没有索引时,没有利用索引,而 and 的一边有索引一边没有索引时 , 却利用了索引。
下面测试 or 和 and 的两边都有索引的情况
select * from student where sid = 5 or id = 10
select * from student where sid = 5 and id = 10
下面测试 or 和 in 的在有索引下的情况
select * from student where sid = 5 or sid = 10
select * from student where sid in ( 5 , 10 )
可以看到在有索引的情况下, in 和 or 的速度差不多。
下面测试没有索引的情况下, in 和 or 的速度:
首先删除索引 drop index stu_sid
运行下面语句 :
select * from student where sid = 5 and id = 10
select * from student where sid in ( 5 , 10 )
两个语句的执行计划都如下 :
所以, in 和 or 在没有索引的情况下速度也是一样的。
总结 :
经过在 DB2 上的测试,如果 or 的左右两边的列都有索引,则可以利用索引,否则(只有一边的列有索引或者两边都没有索引)不能利用索引。而 and 两种情况都可以利用索引。
有人说因为 or 不能利用索引所以要将 or 换成 in, 其实是错的。如果 or 的两边是不同列,则不能换成 in, 如果是同样的列,可以转换成 in 的写法。但是这列如果有索引 in 或者 or 都会利用索引,而且速度一样。这列没有索引的话, in 或 or 都不能利用索引,速度也是一样的。