避免索引失效的一些原则

声明:本文中的所有案例都在MySQL5.7版本下进行实践

索引在数据库优化上提供了很大的帮助,了解一些常见的索引失效原则,对SQL优化会有很大的帮助

复合索引:

1、首先复合索引遵循最佳左前缀匹配原则,即,如果有一个复合索引顺序为(a1,a2,a3),则在使用时,必须要使用上a1列索引,才能使用上a2列索引,如果a1列索引失效了,a2,a3都会失效。复合索引不要跨列使用或者无序使用

2、复合索引,尽量使用全索引匹配,即,如果建立了(a1,a2,a3)复合索引,则尽量将a1,a2,a3三列都使用上

复合索引建立的小技巧

准备数据,创建一张book表,字段如下所示

create table book
(
	bid int(4) primary key,
	name varchar(20) not null,
	authorid int(4) not null,
	publicid int(4) not null,
	typeid int(4) not null 
);

执行查询语句:查询authorid=1且typeid为2或3的 bid字段,按照typeid降序,SQL语句explain如下

 

下面我们对这条SQL语句进行优化,加上索引。我们观察到,SQL中使用到了bid,typeid,authorid列,所以我们建立一个复合索引,包含着三列,但是复合索引的顺序应该是怎么样的呢?可以这样吗(bid,typeid,authorid)? 这样是错的,在SQL语句中虽然编写的时候bid在最前面,但是实际解析的时候,应该是先解析where子句,然后在解析select语句的,所以索引的顺序应该是(typeid,authorid,bid),建立好索引我们再次执行上面的SQL。发现使用到了索引,并且长度为12

alter table book add index idx_tab (typeid,authorid,bid);

那么现在就是最优的了吗?不一定,在where子句中,typeid字段使用到了in关键字,而这个关键字可能会让索引失效,一旦typeid列的索引失效了,等于没有使用上索引(参照复合索引的最佳左前缀原则) 

所以我们可以这样子,将typeid字段和authorid字段换一下位置,将原来的复合索引删掉,创建新顺序的复合索引(authorid,typeid,bid),这样子,即使typeid列的索引失效了,我们也可以使用到authorid列的索引,因为现在是authorid列在前面

小结:

最佳左前缀,保持索引的定义和使用的顺序一致性

索引需要逐步优化

将含in的范围查询 放到where条件的最后,防止失效

 

不要在索引列上做任何操作(计算、函数、类型转换等)

现在我们在book表中,只有(typeid,authorid,bid)顺序的复合索引

执行下面的SQL,由于authorid字段使用了乘法,所以只使用了typeid列的索引,故key_len=4

 执行以下SQL,由于在typeid字段上使用了乘法,所以复合索引直接全部失效(最佳左前缀),故key的值为null

 

不要在索引列上使用不等于或者is null,否则索引失效

现在我们在book表中,只有(typeid,authorid,bid)顺序的复合索引

执行以下SQL,因为我们在typeid列上使用了!=,导致复合索引失效

 

尽量不要使用类型转换(显示、隐式),否则索引失效

在book表的name字段建立单值索引

alter table book add index name_index(name);

执行以下SQL,name字段的类型是varchar,而我们却写name=123,让name进行了一次类型转换,所以索引失效。

 

尽量不要使用or,否则索引失效

在book表中现在有三个索引,name列的单值索引,bid列的主键索引,(typeid,authorid,bid)复合索引

执行以下SQL,我们使用了or关键字,导致索引全部失效

 

我们学习索引优化 ,是一个大部分情况适用的结论,但由于SQL优化器等原因  会导致该结论不是100%正确。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值