文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

为什么SQL查询以%开头索引就失效了呢?

2024-11-30 00:33

关注

建表验证

如果有些朋友不信的话,那么我们来验证一下,首先我们建一张表,然后写入数据,脚本如下:

CREATE TABLE `user`  (
  `ID` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `USER_NAME` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `AGE` int(11) NULL DEFAULT NULL,
  `ADDRESS` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `IP` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `PHONE` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `EMAIL` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`ID`) USING BTREE,
  INDEX `NAME_PHONE`(`USER_NAME`, `PHONE`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

图片

同时我们给 USER_NAME 和 PHONE 建立了联合索引,我们插入数据。

INSERT INTO `baseboot`.`user`(`ID`, `USER_NAME`, `AGE`, `ADDRESS`, `IP`, `PHONE`, `EMAIL`) VALUES ('28715757596573696', '测试人员', 12, '北京市海淀区', '127.0.0.1', '17788779981', '789911@163.com');
INSERT INTO `baseboot`.`user`(`ID`, `USER_NAME`, `AGE`, `ADDRESS`, `IP`, `PHONE`, `EMAIL`) VALUES ('28715757596573697', '开发人员', 22, '北京市海淀区', '127.0.0.1', '17788779981', '789911@163.com');

我们插入两条数据,接下来我们看看效果。

图片

然后我们通过 LIKE 来进行查询。

使用 LIKE '%xxx%'。

图片

使用 LIKE 'xxx%'。

图片

我们使用的是 EXPLAN 来分析我们的 SQL ,对比明显,一个使用了我们创建的索引,另外一个没有使用我们创建的索引,所以,为什么失效了呢?

为什么 LIKE '%xxxx%' 索引失效了?

当我们遇到这个问题的时候,这个题目也是面试官比较喜欢问到的问题,百分号在左和在右的区别是哪里呢?

我们都知道在SQL查询中,LIKE操作符用于模糊匹配字符串。通配符%在LIKE语句中的位置对查询的性能和结果有着显著的影响。当%位于LIKE语句的左边、右边或两边时,它们的行为和效果是不同的。

% 在左边:

% 在右边:

% 在两边:

使 LIKE '%xxx%' 索引生效的操作是什么样子呢?

那么我们如何让在左边的百分号能命中索引,让索引不失效呢?

我们可以这样操作:

图片

也就是说,我们需要把有索引的字段,放在最开始的位置,并且尽量的精确索引的字段,而没有其他的字段,这种情况也是可以命中索引的。

而这种情况下,其实就可以理解为是覆盖索引,就是下图的样子。

图片

那么,什么是覆盖索引呢?

什么是覆盖索引

覆盖索引(Covering Index)是一种特殊的索引结构,其设计初衷是为了提高查询性能。与传统的索引不同,覆盖索引包含了查询所需的所有列,因此,当执行查询时,数据库引擎可以直接从索引中获取所需的数据,而无需回表去访问实际的表数据。

在传统的索引结构中,索引通常只包含被索引列的值和指向表中对应行的指针。当查询需要从表中获取数据时,数据库引擎首先通过索引找到对应的指针,然后再根据这些指针去表中获取实际的数据。这个过程被称为“回表操作”,它增加了查询的IO操作和数据传输的开销,影响了查询性能。

而覆盖索引则避免了回表操作。因为覆盖索引本身已经包含了查询所需的所有列的值,所以数据库引擎在查询时可以直接从索引中获取数据,无需再去访问表。这样就减少了IO操作和数据传输,大大提高了查询效率。

要创建一个覆盖索引,需要确保索引包含了查询中WHERE子句和SELECT子句引用的所有列。这样,当执行查询时,数据库引擎就可以仅通过扫描索引来满足查询的需求,无需访问表。

值得注意的是,虽然覆盖索引可以提高查询性能,但它也会增加数据库的存储空间和索引维护的开销。因此,在设计和使用覆盖索引时,需要权衡其带来的性能提升和额外的存储与维护成本。

总的来说,覆盖索引是一种有效的优化手段,可以在某些情况下显著提高SQL查询的性能。然而,它的使用需要根据具体的查询和数据库环境进行仔细的考虑和测试。

总的来说,%在LIKE语句中的位置对查询性能有着重要影响。为了提高查询性能,尽量避免在LIKE语句的开始处使用%通配符,而是尽量将通配符放在查询模式的末尾或中间位置。同时,合理设计和使用索引也是提高查询性能的关键。

所以,你知道为什么失效了么?

来源:Java极客技术内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯