日期:2014-05-18  浏览次数:20626 次

用or查询无法使用索引?!真的是这样吗??
看过很多文章都说用or索引会失效,例如某文:

“  Select * from table1 where tid=2 or tid=3
  会引起全表扫描,如果tid上有索引,其索引也会失效。



事实真的如此吗??我在sql2000,百万级别的一个表实验了一下,在创建索引情况下,用类似上面or查询仅仅用时一秒不到啊,这叫索引没用嘛?

------解决方案--------------------
自己测试下,这样的说法别全信

至少这个例子肯定索引有效

------解决方案--------------------
OR会引起索引失效的说法是这样来的:
如果是这样一个查询
SELECT * FROM TB WHERE A=1 AND B>2 AND C<3 AND D IN (4,5,6)
并且在TB表上有这样一个索引:CREATE INDEX INX_TB_ABCD ON TB (A,B,C,D)
那么这个查询可以用到这个索引
如果同样是这个索引,查询换成
SELECT * FROM TB_ WHERE A=1 OR B>2 OR C<3 OR D IN (4,5,6)
那么这个查询就用不到上面那个索引,因为结果集是几个条件的并集,最多只能在查找A=1的数据时用索引,其它几个条件都需要表扫描,那优化器就会选择直接走一遍表扫描,所以索引就失效了。

那么像第二个查询这样的应该怎么建索引呢,答案就是四个列上各建一个索引,或者只在选择性最高的列上建索引,比如A=1的数据量很少,就在A上建,如果D是4,5,6的数据很少,就在D上建,这样优化器就会选择先走索引查找,再对找出的结果集进行筛选,扫描数就会大幅减少。

回过头来看你上面那个查询,两个条件都在TID上,所以只有TID上有一个索引就OK了,不存在索引失效的问题。

看书不要全信,多想想书上为什么这么说,自己多试试。