如果你的查询中用到了索引,这是一个进步,如果能够更进一步,用到了覆盖索引,那么就更牛了!当我们设计一个索引的时候,如果能够从一个更加全面的角度去设计这个索引,不仅考虑到 where 中的条件,还能够考虑到整个 SQL,那么无疑这个索引的设计将是非常成功的。
创新互联建站专业为企业提供金沙网站建设、金沙做网站、金沙网站设计、金沙网站制作等企业网站建设、网页设计与制作、金沙企业网站模板建站服务,10余年金沙做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
当然不能为了覆盖而覆盖。
要理解什么是覆盖索引,我们需要先来回顾一下 InnoDB 中索引树的数据结构。
假设我有如下数据:
id(主键) |
username |
age |
address |
gender |
1 |
ab |
99 |
深圳 |
男 |
2 |
bw |
95 |
天津 |
男 |
3 |
cx |
93 |
深圳 |
男 |
4 |
bc |
80 |
上海 |
女 |
5 |
bg |
85 |
重庆 |
女 |
6 |
ac |
98 |
广州 |
男 |
7 |
bw |
99 |
海口 |
女 |
8 |
ck |
90 |
深圳 |
男 |
9 |
cc |
92 |
武汉 |
男 |
10 |
af |
88 |
北京 |
女 |
现在我给 username、age 以及 address 三个字段建立一个联合索引,那么这个联合索引的 B+Tree 可能是这个样子:
上面这个索引树是一个非聚集索引或者也可以说是一个二级索引,这种索引区别于我们之前文章跟大家聊的聚集索引(再聊 MySQL 聚簇索引),在聚集索引中,叶子结点就是这一行的数据,但是在二级索引中,叶子结点中保存的是主键值。
所以,当我们搜索的时候,如果使用的是二级索引,那么最终拿到的是主键值,有了主键值之后,我们还需要再去到聚簇索引中进行搜索,才能拿到完整的数据,这个过程我们也称之为回表。
很明显,如果进行了回表操作的话,那么执行效率显然就要下降一截,那么是否用到了二级索引就会回表呢?其实不然!如果是覆盖索引的话,就不需要回表。
那么什么是覆盖索引呢?
小伙伴们观察上面的索引树,大家发现在这个索引树中,离叶子结点最近的树枝上有 username、age 以及 address,而叶子结点上有 id,所以如果我想要查询的字段是 id、username、age 以及 address 中的任意一个或者任意几个的话,那么就不需要再去聚簇索引上查询了,当前这个 B+Tree 上直接就有现成的,直接返回即可,这个就是覆盖索引。
现在假设我有如下一张表:
CREATE TABLE `user` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`age` int DEFAULT NULL,
`address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`gender` varchar(2) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `user_prop_index` (`username`,`age`,`address`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
可以看到,这张表中有一个名为 user_prop_index 的索引,这个索引中一共存在三个字段,分别是 username、age 以及 address,现在我们来看如下 SQL 的执行计划:
explain select address from user where username='ab' and age=99\G
小伙伴们看到,Extra: Using index 就表示使用到了覆盖索引,因为我的查询 SQL 中最终想要的值,都在当前这棵索引树上。
更进一步,假设我要查询 id、address 以及 age 字段,如下:
explain select id,address,age from user where username='ab'\G
很明显,由于这三个字段都在索引树上,所以直接直接通过回表获取到。
但是,如果想直接 select *,那么由于这个索引树上没有 gender 字段,此时就必须要回表才能拿到 gender 字段的值,如下:
explain select * from user where username='ab'\G
可以看到,这个时候没有用到覆盖索引了。
通过前面的介绍,覆盖索引的优势相信小伙伴们也能自己总结出来:
标题名称:好的索引当然是要覆盖了!
网页地址:http://www.csdahua.cn/qtweb/news18/284968.html
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网