天天看点

DB2存在多个索引时,“强制”DB2使用您期望的索引。

问题引入: 在执行SQL语句时,如果where条件后有多个谓词,对应多个索引,则SQL语句可能会用不同的索引,以下面的SQL为例:

"select * from t1 where col1 = ? and col2 <= ?"

col1和col2上都有索引,那么有没有办法影响SQL语句的访问计划,使其倾向于只使用其中一个索引呢?答案是可以的,你可以告诉DB2,如果使用这个谓词对应的索引,那么匹配的记录数会非常多,效果不好,DB2就会使用另一个索引。或者反之。告诉DB2的方法,就是在谓词后加上selectivity。

下面的例子中,表t1有两个索引col1上有idx1,col2上有idx2。 假设SQL语句"select * from t1 where col1 = ? and col2 <= ?"使用的是索引idx2,如果期望使用索引1,应该怎么办呢?

for i in `seq 1 5`; do seq 1 20000 >> 1.txt; done

seq 1 100000 >> 2.txt

paste -d "," 1.txt 2.txt > t1.del

db2 "create table t1( col1 int, col2 int)"

db2 "create index idx1 on t1(col1)"

db2 "create index idx2 on t1(col2)"

db2 "load from t1.del of del insert into t1 nonrecoverable"

db2 "runstats on table t1 and indexes all"

db2expln -d sample -g -statement "select * from t1 where col1 = ? and col2 <= ?" -terminal

在使用selectivity之后,同样的SQL就走了索引idx1。下面的例子中,在col2谓词后加了selectivity,并给了一个很大的数值0.999(接近1),DB2就会知道,如果使用idx2的话,会有99.9%的记录都满足条件,也就是该索引的效率不高。于是DB2选择了索引idx1

db2set DB2_SELECTIVITY=all -immediate

db2expln -d sample -g -statement "select * from t1 where col1 = ? and col2 <= ? selectivity 0.999" -terminal

注意:

只有在其他办法都试过了,并且没有效果的情况下,才建议使用selectivity。其他方法可以在参考链接中找到:

参考链接:

https://www.ibm.com/developerworks/data/library/tips/dm-0312yip/