在开始测试前先创建测试数据:
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 都不能利用索引,速度也是一样的。