最近在学习mysql索引相关的知识,了解了覆盖索引的概念:如果一个索引包含(或覆盖)所有需要查询的字段的值,称为‘覆盖索引’。即只需扫描索引而无须回表。优点也很明显:要查询的列在当前索引上即可获取到,无需回表查询。
话不多说,直接上例:
CREATE TABLE `t_member_invitationcode` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`customerId` int(11) DEFAULT '0' COMMENT '品牌id',
`memberCode` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '会员卡号',
`invitationCode` int(11) DEFAULT NULL COMMENT '会员邀请码 ',
`createTime` datetime DEFAULT NULL COMMENT '创建时间',
`updateTime` timestamp NULL DEFAULT NULL COMMENT '更新时间',
`isDeleted` tinyint(4) DEFAULT NULL COMMENT '软删 0-未删除 1-删除',
PRIMARY KEY (`id`),
KEY `IX_customerId_memberCode` (`customerId`,`memberCode`,`isDeleted`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='会员邀请码';
上表是会员邀请码记录表,业务场景是根据会员卡号查询其邀请码,sql语句:
SELECT invitationCode from t_member_invitationcode
WHERE customerId=100
and memberCode='13456789012'
and isDeleted=0
explain执行分析如下:
把索引改为:`IX_customerId_memberCode` (`customerId`,`memberCode`,`isDeleted`, `invitationCode`) USING BTREE
再次explain执行分析:
对比可以发现,相同点:都走了IX_customerId_memberCode索引,不同点:当索引中添加了invitationCode字段后,查询的字段可以从当前的索引中直接获取到,无需再根据主键再回表查询。
纸上得来终觉浅,绝知此事要躬行意境。理论还是要结合实践才能理解更深刻。