0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

MySQL索引的使用问题

数据分析与开发 来源:数据分析与开 作者:Harvey 2021-01-06 16:13 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

一、前言

在MySQL中进行SQL优化的时候,经常会在一些情况下,对MySQL能否利用索引有一些迷惑。譬如:1、MySQL 在遇到范围查询条件的时候就停止匹配了,那么到底是哪些范围条件?2、MySQL 在LIKE进行模糊匹配的时候又是如何利用索引的呢?3、MySQL 到底在怎么样的情况下能够利用索引进行排序?今天,我将会用一个模型,把这些问题都一一解答,让你对MySQL索引的使用不再畏惧。

二、知识补充

EXPLAIN执行计划中有一列 key_len 用于表示本次查询中,所选择的索引长度有多少字节,通常我们可借此判断联合索引有多少列被选择了。在这里 key_len 大小的计算规则是:

一般地,key_len 等于索引列类型字节长度,例如int类型为4 bytes,bigint为8 bytes;

如果是字符串类型,还需要同时考虑字符集因素,例如:CHAR(30) UTF8则key_len至少是90 bytes;

若该列类型定义时允许NULL,其key_len还需要再加 1 bytes;

若该列类型为变长类型,例如 VARCHAR(TEXTBLOB不允许整列创建索引,如果创建部分索引也被视为动态列类型),其key_len还需要再加 2 bytes;

三、哪些条件能用到索引

首先非常感谢登博,给了我一个很好的启发,我通过他的文章_,然后结合自己的理解,制作出了这幅图:

乍一看,是不是很晕,不急,我们慢慢来看图中一共分了三个部分:

1、Index Key :MySQL是用来确定扫描的数据范围,实际就是可以利用到的MySQL索引部分,体现在Key Length。

2、Index Filter:MySQL用来确定哪些数据是可以用索引去过滤,在启用ICP后,可以用上索引的部分。

3、Table Filter:MySQL无法用索引过滤,回表取回行数据后,到server层进行数据过滤。下面我们细细展开。Index Key是用来确定MySQL的一个扫描范围,分为上边界和下边界。MySQL利用=、》=、》 来确定下边界(first key),利用最左原则,首先判断第一个索引键值在where条件中是否存在,如果存在,则判断比较符号,如果为(=,》=)中的一种,加入下边界的界定,然后继续判断下一个索引键,如果存在且是(》),则将该键值加入到下边界的界定,停止匹配下一个索引键;如果不存在,直接停止下边界匹配。


		exp:idx_c1_c2_c3(c1,c2,c3)where c1>=1 and c2>2 and c3=1--> first key (c1,c2)--> c1为 '>=' ,加入下边界界定,继续匹配下一个-->c2 为 '>',加入下边界界定,停止匹配上边界(last key)和下边界(first key)类似,首先判断是否是否是(=,<=)中的一种,如果是,加入界定,继续下一个索引键值匹配,如果是(<),加入界定,停止匹配

		exp:idx_c1_c2_c3(c1,c2,c3)where c1<=1 and c2=2 and c3<3--> last key (c1,c2,c3)--> c1为 '<=',加入上边界界定,继续匹配下一个--> c2为 '='加入上边界界定,继续匹配下一个--> c3 为 '<',加入上边界界定,停止匹配

注:这里简单的记忆是,如果比较符号中包含‘=’号,‘》=’也是包含‘=’,那么该索引键是可以被利用的,可以继续匹配后面的索引键值;如果不存在‘=’,也就是‘》’,‘《’,这两个,后面的索引键值就无法匹配了。同时,上下边界是不可以混用的,哪个边界能利用索引的的键值多,就是最终能够利用索引键值的个数。

Index Filter

字面理解就是可以用索引去过滤。也就是字段在索引键值中,但是无法用去确定Index Key的部分。


		exp:idex_c1_c2_c3where c1>=1 and c2<=2 and c3 =1index key --> c1index filter--> c2 c3

这里为什么index key 只是c1呢?因为c2 是用来确定上边界的,但是上边界的c1没有出现(《=,=),而下边界中,c1是》=,c2没有出现,因此index key 只有c1字段。c2,c3 都出现在索引中,被当做index filter.

Table Filter

无法利用索引完成过滤,就只能用table filter。此时引擎层会将行数据返回到server层,然后server层进行table filter。

四、Between 和Like 的处理

那么如果查询中存在between 和like,MySQL是如何进行处理的呢?

Between

where c1 between ‘a’ and ‘b’ 等价于 where c1》=‘a’ and c1 《=‘b’,所以进行相应的替换,然后带入上层模型,确定上下边界即可

Like

首先需要确认的是%不能是最在最左侧,where c1 like ‘%a’ 这样的查询是无法利用索引的,因为索引的匹配需要符合最左前缀原则where c1 like ‘a%’ 其实等价于 where c1》=‘a’ and c1《‘b’ 大家可以仔细思考下。

五、索引的排序

在数据库中,如果无法利用索引完成排序,随着过滤数据的数据量的上升,排序的成本会越来越大,即使是采用了limit,但是数据库是会选择将结果集进行全部排序,再取排序后的limit 记录,而且MySQL 针对可以用索引完成排序的limit 有优化,更能减少成本。

Make sure it uses index It is very important to have ORDER BY with LIMIT executed without scanning and sorting full result set, so it is important for it to use index – in this case index range scan will be started and query execution stopped as soon as soon as required amount of rows generated.

		CREATE TABLE `t1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `c1` int(11) NOT NULL DEFAULT '0', `c2` int(11) NOT NULL DEFAULT '0', `c3` int(11) NOT NULL DEFAULT '0', `c4` int(11) NOT NULL DEFAULT '0', `c5` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`), KEY `idx_c1_c2_c3` (`c1`,`c2`,`c3`)) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4  select * from t1;+----+----+----+----+----+----+| id | c1 | c2 | c3 | c4 | c5 |+----+----+----+----+----+----+| 1 | 3 | 3 | 2 | 0 | 0 || 2 | 2 | 4 | 5 | 0 | 0 || 3 | 3 | 2 | 4 | 0 | 0 || 4 | 1 | 3 | 2 | 0 | 0 || 5 | 1 | 3 | 3 | 0 | 0 || 6 | 2 | 3 | 5 | 0 | 0 || 7 | 3 | 2 | 6 | 0 | 0 |+----+----+----+----+----+----+7 rows in set (0.00 sec)  select c1,c2,c3 from t1;+----+----+----+| c1 | c2 | c3 |+----+----+----+| 1 | 3 | 2 || 1 | 3 | 3 || 2 | 3 | 5 || 2 | 4 | 5 || 3 | 2 | 4 || 3 | 2 | 6 || 3 | 3 | 2 |+----+----+----+7 rows in set (0.00 sec)

	

存在一张表,c1,c2,c3上面有索引,select c1,c2,c3 from t1; 查询走的是索引全扫描,因此呈现的数据相当于在没有索引的情况下select c1,c2,c3 from t1 order by c1,c2,c3; 的结果。因此,索引的有序性规则是怎么样的呢?c1=3 —》 c2 有序,c3 无序 c1=3,c2=2 — 》 c3 有序 c1 in(1,2) —》 c2 无序 ,c3 无序

有个小规律,idx_c1_c2_c3,那么如何确定某个字段是有序的呢?c1 在索引的最前面,肯定是有序的,c2在第二个位置,只有在c1 唯一确定一个值的时候,c2才是有序的,如果c1有多个值,那么c2 将不一定有序,同理,c3也是类似

六、小结

针对MySQL索引,我这边只是提到了在单表查询情况下的模型,通过这篇文章,想必大家应该了解到MySQL大部分情况下是如何利用索引的。

责任编辑:xj

原文标题:MySQL 的索引是如何工作的?10 分钟讲清楚!

文章出处:【微信公众号:数据分析与开发】欢迎添加关注!文章转载请注明出处。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • MySQL
    +关注

    关注

    1

    文章

    938

    浏览量

    29845
  • 索引
    +关注

    关注

    0

    文章

    60

    浏览量

    10863

原文标题:MySQL 的索引是如何工作的?10 分钟讲清楚!

文章出处:【微信号:DBDevs,微信公众号:数据分析与开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    系统讲解MySQL慢查询的完整排查流程

    MySQL 慢查询是影响业务响应速度的最常见根因。业务高峰期一次看似简单的 SELECT 查询,可能拖慢整个系统——前端页面加载转圈、API 超时、后台任务堆积、数据库连接池耗尽。更要命的是,慢查询
    的头像 发表于 05-11 16:50 322次阅读

    SGG-北京总部Java20250625-12月结课

    、Maven 依赖管理、持续集成/持续部署(CI/CD)流水线以及 Docker 容器化技术融入实战项目。 此外,针对企业级应用中不可或缺的数据存储与消息中间件,课程涵盖了 MySQL索引优化与锁
    发表于 05-01 17:33

    MySQL数据库慢查询的排查思路和最佳实践

    数据库慢查询是导致应用响应缓慢最常见的原因之一。当业务人员反馈“页面加载慢”、“查询超时”、“系统卡顿”时,很多运维人员的第一反应是让开发人员“加个索引”。但加索引只是优化查询的众多手段之一,盲目加索引不仅可能无效,还可能适得其
    的头像 发表于 04-24 14:40 220次阅读

    全方位对比:Redis能取代MySQL吗?看完这篇你就懂了

    Redis能不能取代MySQL?答案很明确:不能取代,但可以互补。
    的头像 发表于 04-07 10:50 260次阅读
    全方位对比:Redis能取代<b class='flag-5'>MySQL</b>吗?看完这篇你就懂了

    MySQL慢查询分析与索引调优全流程

    MySQL 性能问题在生产环境中的表现通常是渐进式的:业务量增长、数据量膨胀,某天突然发现 P99 响应时间从 50ms 涨到 2s。慢查询是最常见的根因,而索引设计不合理又是慢查询的主要来源。
    的头像 发表于 03-06 15:56 307次阅读

    恒讯科技解析:如何安装MySQL并创建数据库

    安装和管理MySQL不必复杂。只需几分钟,你就能在Linux服务器上搭建MySQL,创建第一个数据库,甚至自动化备份——同时确保数据安全有序。 什么是 MySQL  MySQL 是一个
    的头像 发表于 01-14 14:25 477次阅读

    工业数据中台支持接入MySQL数据库吗

    工业数据中台完全支持接入MySQL数据库 ,且通过数据同步、集成与治理等技术手段,能够充分发挥MySQL在数据存储与事务处理方面的优势,同时弥补其在数据分析与共享能力上的不足,具体分析如下: 技术
    的头像 发表于 12-04 11:23 566次阅读
    工业数据中台支持接入<b class='flag-5'>MySQL</b>数据库吗

    Hudi系列:Hudi核心概念之索引(Indexs)

    上的Instant action操作类型 ▪1.4 时间线上State状态类型 ▪1.5 时间线官网实例 ◦二. 文件布局 ◦三. 索引 3.1 简介 3.2 对比其它(Hive)没有索引的区别 3.2
    的头像 发表于 10-21 09:47 598次阅读
    Hudi系列:Hudi核心概念之<b class='flag-5'>索引</b>(Indexs)

    MySQL性能优化实战

    你是否遇到过这些场景:凌晨3点被告警电话吵醒,数据库CPU飙到100%?一条简单的查询语句要跑30秒?明明加了索引,查询还是慢如蜗牛?
    的头像 发表于 09-17 16:19 666次阅读

    MySQL慢查询终极优化指南

    作为一名在生产环境摸爬滚打多年的运维工程师,我见过太多因为慢查询导致的线上故障。今天分享一套经过实战检验的MySQL慢查询分析与索引优化方法论,帮你彻底解决数据库性能瓶颈。
    的头像 发表于 08-13 15:55 1019次阅读

    CentOS 7下MySQL 8双主热备高可用架构全解

    Centos7部署MySQL8+keepalived双主热备(含Keepalived配置与GTID同步优化方案) 架构拓扑原理 GTID同步 VIP 192.168.1.100 MySQL主节点1
    的头像 发表于 08-12 17:08 1058次阅读

    MySQL 8.0性能优化实战指南

    作为一名运维工程师,MySQL数据库优化是我们日常工作中最具挑战性的任务之一。MySQL 8.0作为当前主流版本,在性能、安全性和功能上都有了显著提升,但如何充分发挥其潜力,仍需要我们掌握正确的优化策略。
    的头像 发表于 07-24 11:48 1210次阅读

    MySQL的组成结构与结构化查询语言详解

    MySQL作为世界上最流行的开源关系型数据库管理系统,采用了分层架构设计
    的头像 发表于 07-14 11:21 825次阅读

    MySQL数据备份与恢复策略

    数据是企业的核心资产,MySQL作为主流的关系型数据库管理系统,其数据的安全性和可靠性至关重要。本文将深入探讨MySQL的数据备份策略、常用备份工具以及数据恢复的最佳实践,帮助运维工程师构建完善的数据保护体系。
    的头像 发表于 07-14 11:11 966次阅读

    企业级MySQL数据库管理指南

    在当今数字化时代,MySQL作为全球最受欢迎的开源关系型数据库,承载着企业核心业务数据的存储与处理。作为数据库管理员(DBA),掌握MySQL的企业级部署、优化、维护技能至关重要。本文将从实战角度出发,系统阐述MySQL在企业环
    的头像 发表于 07-09 09:50 984次阅读