技术分享 | MySQL 覆盖索引优化案例一则

MySQL索引优化系列:(一,中高级Java面试题目汇总解答 这里,CLUSTERED INDEX是用来建立聚簇索引的关键字,此语句的意思是在表mytable上的mycolumn字段上创建一个名为myclumn_cindex的聚簇索引,且为唯一索引。 阅读详情

作者:刘晨

网名 bisal ,具有十年以上的应用运维工作经验,目前主要从事数据库应用研发能力提升和技术管理相关的工作,Oracle ACE(Alumni),腾讯云TVP,拥有 Oracle OCM & OCP 、EXIN DevOps Master 、SCJP 等国际认证,国内首批 Oracle YEP 成员,OCMU 成员,《DevOps 最佳实践》中文译者之一,优快云 & ITPub 专家博主,公众号"bisal的个人杂货铺",长期坚持分享技术文章,多次在线上和线下分享技术主题。

本文来源:原创投稿

*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。


最近有个MySQL的SQL性能问题,原理可能很基础,但考察的就是能不能将"显而易见"的知识应用到实践中。

经过脱敏的SQL如下所示,对test表中的c1列进行聚类,再通过SUM … CASE WHEN…等函数进行统计,test表数据量500万,当前检索用时55秒,需求是将执行降到秒级,

SELECT c1,·
       SUM(CASE WHEN c2=0 THEN 1 ELSE 0 END) as folders,
       SUM(CASE WHEN c2=1 THEN 1 ELSE 0 END) as files,
       SUM(c3)
FROM  test
GROUP BY c1;

为了更好地说明,创建一张测试表,主键字段是id,除了c1、c2、c3字段外,还有其他字段,有很多索引,但和c1、c2、c3相关的,只是idx_test_01,c1作为前导列的复合索引,且c2和c3不在索引中,

CREATE TABLE test (
  id bigint(20) not null,
  c1 varchar(64) collate utf8_bin not null,
  c2 tinyint(4) not null,
  c3 bigint(20) default null,
  ...
  primary key(id),
  key idx_test_01(c1, ...)
  key ...
  ...
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

显而易见,如上SQL执行时,能用到的索引就只有idx_test_01,Extra是NULL,

+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type  | possible_keys | key         | key_len | ref  | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-------+
|  1 | SIMPLE      | test  | NULL       | index | idx_test_01   | idx_test_01 | 206     | NULL |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+-------+---------------+-------------+---------+------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

我们知道,MySQL的索引默认是聚簇索引(可以理解为Oracle的IOT索引组织表),针对当前仅有(c1, …)这个复合索引,当执行检索时,即便能使用这个复合索引,他都需要执行两个操作,(1)访问(c1, …)复合索引;(2)从该复合索引中得到主键id,再进行回表,根据主键id,得到相应数据。这个过程中,最需要消耗的,就是磁盘IO的资源。不仅需要访问(c1, …)复合索引的数据,还需要回表,访问数据行。

设计索引应该考虑到整个查询,不单只是WHERE条件。索引是能高效找到数据的方式,但是如果使用索引可以直接得到列的数据,即索引的叶子节点中已经包含要查询的数据,就无需回表,读数据行了。如果一个索引包含(或者叫做覆盖)所有要查询的字段的值,就可以称之为"覆盖索引",但是要注意,只有B-tree索引可以用于覆盖索引。

覆盖索引能显著提高检索的性能,原因就是查询只需要扫描索引而无需回表,

1.索引条目通常远小于数据行大小,因此如果只需要扫描索引,就会极大地减少数据访问量。数据访问响应时间大部分花费在数据拷贝上,索引比数据更小,更容易全部放入内存中。

2.因为索引是按照列值的顺序存储的,所以范围查询会比随机从磁盘读取每一行数据消耗的IO少得多。

3.由于InnoDB的聚簇索引的特点,覆盖索引对InnoDB表特别有用,因为InnoDB的二级索引在叶子节点中保存了记录的主键值,所以如果二级索引能够覆盖查询,则可以避免对主键索引的二次查询。

在索引中满足查询的成本一般比查询记录本身要小得多。

因此,针对这条SQL,创建包含了(c1, c2, c3)的复合索引,

create index idx_test_02(c1, c2, c3) on test;

此时执行SQL,Extra显示Using index,说明用到了覆盖索引的特性,


+----+-------------+-------+------------+-------+-------------------------+-------------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys           | key         | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+-------+-------------------------+-------------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test  | NULL       | index | idx_test_01,idx_test_02 | idx_test_02 | 204     | NULL |    1 |   100.00 | Using index |
+----+-------------+-------+------------+-------+-------------------------+-------------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

从执行效率上,原来跑55秒的语句,现在只需要2秒。

根据2-8原则,可能我们平时碰到的SQL优化,很多都可以用基础的知识解决,只有一小部分,需要一些技巧,或者更深层次的知识,但这些所谓的基础知识,“了解"和"理解”,存在着区别,单从知识来讲,可能都知道是怎么个原理,但当碰到实际的场景,能不能将知识运用到实践中,就取决于对知识的理解程度了,这个不仅仅指数据库领域,其它任何领域,都是相通的,学习知识,重要的是能应用到实践中,能做到举一反三,这个的前提就是对知识是不是真正理解了,而不是停留在表面上。

因此,我们学习任何知识的时候,一定要强调理论和实践的结合,多积累经验,毕竟解决问题,才是我们大多数职场人学习的目标。

覆盖索引及案例 覆盖索引 技巧 1. 创建覆盖索引的方法 2. 使用Order by和distinct后,如何创建覆盖索引 立即下载

相关推荐

Mysql性能优化案例研究-覆盖索引和SQL_NO_CACHE

场景 产品中有一张图片表pics,数据量将近100万条,有一条相关的查询语句,由于执行频次较高,想针对此语句进行优化 表结构很简单,主要字段: 代码如下: user_id 用户ID picname 图片名称 smallimg 小图名称 一个用户会有多条图片记录,现在有一个根据user_id建立的索引:uid,查询语句也很简单:取得某用户的图片集合: 代码如下: select picname, smallimg from pics where user_id = xxx; 优化前 执行查询语句(为了查看真实执行时间,强制不使用缓存,为了防止在测试时因为读取了缓存造成对时间上的差别) 代码

关于mysql索引覆盖的实例

mysql 索引覆盖

a729885163的博客 1526

在C++中,NULL和nullptr有什么区别?

这两个定义导致了冲突,C++中的NULL如果和C语言一样也是(void *)0指针,而C++不允许void*隐式转换成其它指针类型,那NULL就无法表示空指针了。因此,使用 nullptr可以增加代码的清晰性,避免类型安全问题。即使在混合C++和C代码时,nullptr也提供了一个明确无误的空指针表示,达到兼容的目的。C++11 引入 nullptr 彻底解决了这些问题,提高语言的安全性、清晰性和现代性。在了解NULL和nullptr背后的故事之后,相信大家以后再也不会用NULL了。

hebhljdx的博客 678

MySQL覆盖索引

一、覆盖索引 覆盖索引(covering index)指一个查询语句的执行只用从索引中就能够取得,不必从数据表中读取。也可以称之为实现了索引覆盖。 如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。二、覆盖索引实例 1.未建立索引前 select SQL_NO_CACHE count(name) from index_test where name = '小明' and id_card = '142701199999999999' and type = '2' and h.

I want to know a little more. 595

《遥感大模型生产级实战:从数据到决策的端到端AI工程》系列第三部分:城市洪涝灾害应急响应与评估平台实战-文章 14:项目二启动与多源异构数据对齐

我们将系统性地梳理城市洪涝场景下的所有关键数据源,从天上的卫星(光学与SAR)、空中的无人机,到地面的物联网传感器和社交媒体信息流,深入剖析每种数据在洪涝响应中的独特价值、获取方式与内在局限性。本章的核心将是一个详尽的、生产级的数据对齐技术全景,我们将分步解决三大核心对齐难题:空间对齐(将所有数据投影到统一的地理坐标系)、时间对齐(处理不同采样频率的时间序列)以及最困难的语义对齐(将文本描述与物理观测相关联)。

panshengwu的博客 2003

华硕主板UEFI模式下安装Ubuntu与Windows双系统全攻略

本文详细讲解了在华硕主板UEFI模式下安装Ubuntu与Windows双系统的完整流程。从安装前的BIOS关键设置(如处理安全启动与CSM)、使用GPT分区表,到在Windows中安全分配空间、手动创建Ubuntu分区,最后完成引导配置,提供了避免常见错误的实用技巧,确保双系统稳定共存。

weixin_29199873的博客 345

覆盖索引的理解与举例

此时根据name会找到 主键id 此时只能返回id和name而不能返回password,这时就会回表查询找到对应的行消耗了性能,如果我们建立一个联合索引name,password 那么在找到name的同时也会找到passwode同时非聚簇索引叶子结点会存储主键id值这是就能直接返回这三个字段而不用进行回表查询,这样就提高了效率 ,但是如果我们再加入一个字段grade就会又需要回表查询了。覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。

qq_52896055的博客 425

超级详细的H3C模拟器HCL的交换机Telnet服务配置过程(图文)

VC++2017 MFC关于一个电话机房配线架进线出线节点数据库管理的程序 机房数据库原来是一个EXCEL表,查询,输入数据不方便。现用access数据库ODBC访问。平常没编过程序,编个程序练练手。记录一下学习中的问题,和解决方法,供大家分享,讨论,以便共同进步。希望多提宝贵意见,携手提高代码水平。 程序写的很不规范,代码冗余,显得程序臃肿,代码重用性差。发表这篇博客的目的也是为了改进这个程序。CListCtrl 单元格可以编辑,有Combo Box下拉列表功能。使用PreTranslateMe

techcai的博客 1万+

MySQL的回表查询与索引覆盖

博客主页:🏆看看是李XX还是李歘歘🏆 🌺每天不定期分享一些包括但不限于计算机基础、算法、后端开发相关的知识点,以及职场小菜鸡的生活。🌺 💗点关注不迷路,总有一些📖知识点📖是你想要的💗 ⛽️今天的内容是 MySQL的回表查询与索引覆盖 ⛽️💻💻💻 回表查询 InnoDB索引分为两大类,一类是聚集索引(Clustered Index),一类是非聚集索引(Secondary Index) 聚集索引(聚簇索引):叶子节点中存的是整行数据,找到索引也就找到了数据,索引即数据,表中行...

分享包括但不限于计算机基础知识、数据结构与算法、Golang技术栈。年与时驰,意与日去,遂成枯落,多不接世,悲守穷庐,将复何及! 6098

RK3588平台开发系列讲解(DMA篇)DMA engine使用

Linux 内核的 DMA 引擎提供了一组完整的接口,用于申请和释放 DMA 通道、准备 DMA 描述符、启动和控制 DMA 传输,以及同步和管理缓存。通过这些接口,内核能够高效地处理异步的 DMA 传输任务,减少 CPU 的干预,提高数据传输的效率。

内核笔记 1832

芒果YOLOv1改进35:主干Backbone篇之MobileViTv3:全网首发最新 MobileViTv3 系列最强改进版本(三)|轻量化Transformer视觉转换器,简单有效地融合了本地全局

芒果YOLOv1改进35:主干Backbone篇之MobileViTv3:全网首发最新 MobileViTv3 系列最强改进版本(三)|轻量化Transformer视觉转换器,简单有效地融合了本地全局

包括YOLOv5、YOLOv7、YOLOv8等模型改进 408

MySQL中聚集索引、非聚集索引、联合索引、覆盖索引

在《面试官:为啥加了索引查询会变快?》一文中,我们介绍了索引的数据结构,正是因为索引使用了B+树,才使得查询变快。说白了,索引的原理就是减少查询的次数、减少磁盘IO,达到快速查找所需数据的目的 我们一起来看一下InnoDB存储引擎中的索引 聚集索引 聚集索引(clustered index)就是按照每张表的主键构造一棵B+树,同时叶子节点中存放的即为整张表的行记录数据,也将聚集索引的叶子节点称为数据页。聚集索引的这个特性决定了索引组织表中数据也是索引的一部分 (备注:真实的B+树叶子节点是通过链表相连的,

果子爸聊技术 2万+

2025国赛数学建模A题 完整Python代码 烟幕干扰弹的投放策略

常量定义G = 9.8 # 重力加速度 m/s²V_SMOKE_SINK = 3 # 烟幕下沉速度 m/sMISSILE_SPEED = 300 # 导弹速度 m/sEFFECTIVE_RADIUS = 10 # 有效遮蔽半径 mEFFECTIVE_DURATION = 20 # 有效遮蔽时间 sTARGET_POS = np.array([0, 200, 0]) # 目标位置FALSE_TARGET_POS = np.array([0, 0, 0]) # 假目标位置# 初始位置。

YOLO 1105

MySQL 查询优化案例分享

在日常开发中,SQL 查询性能直接影响到系统的响应速度和用户体验。随着数据量的增长,慢查询可能成为系统的瓶颈。本文将通过实际案例,分享几种常见的 MySQL 查询优化方法,帮助开发者快速定位和优化慢查询,提升数据库性能。希望通过以上案例分享,帮助开发者在实际项目中有效优化 MySQL 查询,提升系统整体性能。通过开启慢查询日志,可以记录执行时间超过指定阈值的 SQL 查询,帮助分析系统中的瓶颈。分页查询性能较差,用户访问较深的分页时响应时间缓慢。中近一年的订单数据,查询速度缓慢。操作,执行时间过长。

秋元的博客 1430

从登录到应用可见:在 SAP S/4HANA Cloud Private Edition 中创建用户与打通 SAP Fiori 权限的完整思路

在SAP S/4HANA系统中,用户创建远非简单的账号开通,而是涉及认证、授权、数据访问等多维度的复杂过程。用户主数据记录(User Master Record)是系统访问的起点,包含登录方式、角色分配等关键信息。认证解决"你是谁"的问题,授权则决定"你能做什么"。SAP Fiori访问链路涉及Launchpad内容分配、应用启动映射、OData服务权限等多层校验。角色(Role)通过PFCG维护,包含业务目录(Catalog)和空间(Space)等元素,共同构成完整

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 148

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

MySQL优化:如何避免回表查询?_什么是索引覆盖?

数据库表结构: create table user ( id int primary key, name varchar(20), sex varchar(5), index(name) )engine=innodb; select id,name where name='shenjian' select id,name,sex where name='shenjian' 多查询了一个属性,为何检索过程完全不同? 什么是回表查询? 什么是索引覆盖? 如何实现索引覆盖?

qq_43842093的博客 4506

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

MySQL索引优化案例学习总结

目录 一、概述 二、创建表以及初始化数据 三、全值匹配原则 四、最佳左前缀原则 五、避免在索引列上进行任何操作 六、存储引擎不能使用索引中范围条件右边的列 七、尽量使用覆盖索引 八、避免使用不等于 (!= 或者 <>)操作 九、避免使用is null, is not null判空/非空操作 十、谨慎使用like通配符模糊查询 十一、避免隐式类型转换导致索引失效 十二、尽量少用or连接操作 十三、联合索引案例分析 十四、总结 一、概述 我们都知道,索引是一种排好序的

weixiaohuai的博客 870

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

MySQL索引优化指南:如何科学地为数据表添加索引

MySQL索引优化指南 索引是提升数据库查询性能的关键工具。本文系统介绍了索引的使用场景与优化策略: 何时加索引 高频查询条件、JOIN字段、排序分组列 高选择性列(唯一值多)和大表查询 何时避免索引 小表、低选择性列(如性别) 频繁更新字段和不用于查询的列 优化方法 使用EXPLAIN分析查询执行计划 遵循最左前缀原则设计复合索引 监控慢查询日志和未使用索引 最佳实践 优先优化高频查询 避免过度索引影响写入性能 定期重建索引保持效率 通过科学评估查询模式,合理设计索引,

私聊前往站内信:https://i.youkuaiyun.com/#/msg/chat/weixin_44976692 1万+

mysql优化语句之回表查询 索引覆盖 利用索引覆盖来优化SQL

mysql优化语句之回表查询 索引覆盖 利用索引覆盖来优化SQL

qq_36078699的博客 1093

MySQL - 性能优化实战:从慢查询日志到索引优化全流程

MySQL性能优化实战:从慢查询到索引优化 本文通过电商订单查询场景,详细介绍MySQL性能优化的全流程: 1️⃣ 开启慢查询日志 配置my.cnf启用慢查询记录 设置阈值并分析日志定位问题SQL 2️⃣ 执行计划分析 使用EXPLAIN诊断全表扫描和文件排序问题 解读type、rows、Extra等关键指标 3️⃣ 索引设计优化 遵循最左前缀原则设计联合索引 将等值条件列放在索引前列 包含排序字段避免filesort 4️⃣ 效果验证 对比优化前后的执行计划差异 通过查询耗时验证性能提升 优化后案例:订单

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

mysql覆盖索引与回表

select id,name where name='shenjian' select id,name,sex* where name='shenjian'* 多查询了一个属性,为何检索过程完全不同? 什么是回表查询? 什么是索引覆盖? 如何实现索引覆盖? 哪些场景,可以利用索引覆盖来优化SQL? 这些,这是今天要分享的内容。 画外音:本文试验基于MySQL5.6-InnoDB。 ...

qq_35936776的博客 2273

深入浅出Mysql索引优化专题分享|面试怪圈

该文章结合18张手绘图例,21个SQL经典案例、近10000字,将Mysql索引优化经验予以总结

866

如何避免回表查询?什么是索引覆盖? | 1分钟MySQL优化系列

《迅猛定位低效SQL?》留了一个尾巴:select id,name where name='shenjian'select id,name,sex where name=...

shenjian58的博客 3375

MongoDB覆盖索引查询优化策略

在众多数据库技术中,MongoDB以其灵活的数据模型和强大的查询能力而备受关注。然而,在实际应用中,我们常常会遇到查询效率低下的问题,尤其是在处理大量数据时。为了解决这一问题,MongoDB引入了覆盖索引查询的概念。下面,我们将深入探讨这一知识点。在传统的数据库查询中,我们通常需要通过索引来提高查询效率。然而,当查询条件涉及到索引字段以外的字段时,数据库仍然需要执行全表扫描,导致查询效率低下。而覆盖索引查询则可以避免这一问题。覆盖索引查询,顾名思义,是指查询操作仅依赖于索引,无需访问数据文档本身。

我是Java程序员廖志伟,感谢朋友们的支持! 869

一看就会的mysql索引优化(真实案例)

背景 (使用的数据库:MYSQL 5.7 版本,InnoDB 引擎) 自从服务加了Skywalking后,将大部分慢接口暴露出来。于是就有了这次慢接口的优化。大概的优化过程,没有详细的具体过程 优化前: 优化后: 优化步骤 1. 排查 通过skywalking可以清楚的看到慢接口是在哪一步比较慢。通过调用情况可以清楚的看到其链路调用情况如下图: 如果说你的服务没有接如这种情况监控服务,那我们可以使用阿里巴巴开源的Arthas来进行链路追踪(使用trace进行查看每一步方法的调用耗时)a

weixin_40413961的博客 1755

mysql优化案例分享

mysql5.5.8版本开始后。InnoDB引擎就是默认存储引擎,本文介绍知识点也都是围绕该引擎展开。知识点1聚集存储InnoDB引擎采用聚集存储,即每张表的存储都是主键的顺序进行存放,也就是每行存储的物理顺序和主键顺序相同,如果未指定主键,引擎会为每张表生成一个6字节的rowid作为主键。相对于非聚集存储,聚集存储会同时存储索引和数据。知识点2 B+树索引。

coding change your life 1902
上一篇: 技术分享 | 使用 RPM 部署 Oceanbase Proxy
下一篇: 故障分析 | Redis AOF 重写源码分析
爱可生开源社区
博客等级 码龄8年 1936粉丝 1004原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值