索引需要注意的问题

1、IN操作符

用IN操作符写出来的SQL直观简单、易于理解。但是在where条件中使用IN操作符是低效的。例如下面这条查询语句:

SELECT *

FROM tab_a

WHERE id IN(

SELECT a_id FROM tab_b);

你认为它会怎么执行呢?先从tab_a表中遍历数据,然后拿每行数据的id字段去tab_b表中去查找,只要找到就把这行纳入查询结果。

大错特错!事实上,RDBMS会先执行第4行的子查询,把查出的数据保存到一张临时表中,再执行主查询,利用临时表中的数据去核对主查询的where条件是否成立。

这是IN操作符低效的主要原因,因为临时表是没有索引的,要核对当前数据行的id值在临时表中是否出现,必须遍历临时表。也就是说tab_b表中即使对a_id字段建了索引也是没有用的。

推荐方案是使用表连接:

SELECT tab_a.*

FROM tab_a INNER JOIN tab_b

ON tab_a.id=tab_b.id;

或者使用EXISTS操作符:

SELECT *

FROM tab_a

WHERE EXISTS

SELECT *

FROM tab_b

WHERE tab_a.id=tab_b.a_id;

注意,NOT IN和IN存在类似的问题,也是无法利用表上的索引。

2、IS NULL和IS NOT NULL

值得一提的是,数据库是不索引空值的,也就是说即便你在一个字段上建立的索引,当针对这个字段进行查询时,还是需要遍历整张表。

3、LIKE

LIKE操作符用于模糊查询,通过使用通配符可以进行非常灵活的查询,但是如果运用不当则会造成索引失效从而影响性能。

例如,LIKE '%abc%'这种两头都带通配符的查询不会使用到索引,而LIKE 'abc%'会使用到索引来缩小查询范围,从而提高性能。

4、where条件中的函数

where条件中如果出现函数则索引会失效,例如下面的查询语句:

SELECT *

FROM tab

WHERE substring(name,1,3)='abc';

where条件中队name字段进行了取子串的函数转换,这样,即便name字段上建了索引,这个索引在查询的时候也不会被用到。

对于这种情况,即便是下面这条语句,也比上面的那条要强得多:

SELECT *

FROM tab

WHERE NAME LIKE 'abc%'

5、where条件中表内字段相互交杂**

在where条件中,如果出现本表内的字段相互连接或比较,则字段上的索引是无法生效的,比如下面的语句:

SELECT *

FROM tab

WHERE name||gener = 'abcF'

name和gender上即使有索引,也不起作用。

下面的语句也是类似的情况:

SELECT *

FROM tab

WHERE age>score

age字段和score字段都是tab表的字段,相互比较,不会引用索引。

在处理!=的时候,索引失效。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值