SQL治理经验谈:索引覆盖

news2024/9/22 15:25:43

4a13b94680a0ae736b46540b82a749dc.jpeg

背景

explain - format

  • id: query sql 的标识id

  • SELECT_TYPE: 查询的类型(SIMPLE/PRIMARY/SUBQUERY/DERIVED/UNION/UNION RESULT/DEPENDENT SUBQUERY/DEPENDENT UNION)

  • table: 表名

  • Partitions: 表连接的分区数

  • type: 查询中使用的访问类型(system/const/eq_ref/ref/range/index/ALL),见下表type的字段解析

  • possible_keys

    • 显示可能应用在这张表中的索引,一个或多个。

    • 查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用

  • key

    • 实际使用的索引,如果为NULL,则没有使用索引.

    • 查询中若使用了覆盖索引,则该索引和查询的select字段重叠

  • key_len: 使用到的索引的长度

  • ref: 显示了查询条件类型(const/field_name/func

  • rows: query查询到的行数量

    • query完成索引命中之后,才会去检查的行总数

    • 估算性能耗时:rows用来表示在SQL执行过程中会被扫描的行数,该数值越大,意味着需要扫描的行数,相应的耗时更长。但是需要注意的是EXPLAIN中输出的rows只是一个估算值,不能完全对其百分之百相信,如EXPLAIN中对LIMITS的支持就比较有限。可以参考文章《MySQL EXPLAIN limits and errors》

    • 这个rows就是mysql认为必须要逐行去检查和判断的记录的条数。

  • Filtered: where子句的过滤条件

  • Extra: query子句执行的附加信息

expalin - type

System NameColorText on Visual DiagramTooltip Related Information
SYSTEMBlueSingle row: system constantVery low cost
CONSTBlueSingle row: constantVery low cost
EQ_REFGreenUnique Key LookupLow cost -- The optimizer is able to find an index that it can use to retrieve the required records. It is fast because the index search directly leads to the page with all the row data
REFGreenNon-Unique Key LookupLow-medium -- Low if the number of matching rows is small; higher as the number of rows increases
FULLTEXTYellowFulltext Index SearchSpecialized FULLTEXT search. Low -- for this specialized search requirement
REF_OR_NULLGreenKey Lookup + Fetch NULL ValuesLow-medium -- if the number of matching rows is small; higher as the number of rows increases
INDEX_MERGEGreenIndex MergeMedium -- look for a better index selection in the query to improve performance
UNIQUE_SUBQUERYOrangeUnique Key Lookup into table of subqueryLow -- Used for efficient Subquery processing
INDEX_SUBQUERYOrangeNon-Unique Key Lookup into table of subqueryLow -- Used for efficient Subquery processing
RANGEOrangeIndex Range ScanMedium -- partial index scan
INDEXRedFull Index ScanHigh -- especially for large indexes
ALLRedFull Table ScanVery High -- very costly for large tables, but less of an impact for small ones. No usable indexes were found for the table, which forces the optimizer to search every row. This could also mean that the search range is so broad that the index would be useless.
UNKNOWNBlackunknownNote: This is the default, in case a match cannot be determined

实践

建表

CREATE TABLE `test_like` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '账号',
  `age` int NOT NULL DEFAULT '0' COMMENT '年龄',
  `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '邮箱'
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

测试数据

INSERT into test_like 
(id, name, age, email)
values
(1, 'aaa', 111, '1111'),
(2, 'aaa', 111, '1111'),
(3, 'aaa', 111, '1111'),
(4, 'aaa', 111, '1111'),
(5, 'aaa', 111, '1111');

添加单列索引

-- 单索引 索引覆盖,通过索引idx_on_name的B+树的页节点,可以直接过滤到
ALTER table test_like add key idx_on_name (`name`);

验证案例

案例一:全列检索 select *

测试结果
  • 通配符在右侧

explain select * from test_like where name like '11%';

e294a7843af2eec4b5aaf2e10d378742.png

单列索引,通配符在右侧,select * 会走索引,type=range检索性能好

  • 通配符在左右两侧

explain select * from test_like where name like '%11%';

93a519a902b9a61e86754029a98f9f2f.png

单列索引,通配符在左右两侧,select * 不会走索引,type=ALL检索性能差

  • 通配符在左侧

explain select * from test_like where name like '%11';

3f5fc2972732188e50b79e9c0b26a036.png

单列索引,通配符在左侧,select * 不会走索引,type=ALL检索性能差


结果说明

加了单列索引还不够,因为select 列 和 where 条件语句 两个变量,都可能导致sql执行效果走了全表扫描,性能非常差。想要性能过得去,得确保通配符在右侧。

案例二:索引列检索 select [索引列]

测试结果
  • 通配符在右侧

29058942f542972e9e78c9d69874ed53.png

单列索引,通配符在右侧,select [索引列] 会走索引,type=range检索性能好

  • 通配符在左右两侧

explain select * from test_like where name like '%11%';

024a2ce910808e54a2f69d1966a3d836.png

单列索引,通配符在右侧,select [索引列] 会走索引,

type=index,检索性能和二级索引树的数据量相关;sql性能随着二级索引树节点数量变多,性能变差

  • 通配符在左侧

explain select * from test_like where name like '%11';

8ae20cbeeb2c4125f4b8550a4db20da7.png

单列索引,通配符在左侧,select [索引列] 会走索引,

type=index,检索性能和二级索引树的数据量相关;sql性能随着二级索引树节点数量变多,性能变差


结果说明

案例一的select * 性能优化,可以通过案例二的方法去优化:

  • select [索引列] 因为索引覆盖,所以会避免了全表扫描的结果,最终性能有提高

案例三:联合索引列检索 select [多索引列]

我们对表的 name、age设置了联合索引

-- 联合索引 索引覆盖,通过联合索引idx_on_name_age的页节点,可以直接过滤到
ALTER table test_like add key idx_on_name_age (`name`, `age`);

测试结果

select 满足最左匹配原则 - 单列
  • select [联合索引左侧单列] + 通配符在右侧

explain select name from test_like where name like '11%';

33527ea230904e977b7884c30bf89f35.png

联合索引,通配符在右侧,select [索引列] 会走索引,type=range检索性能好

  • select [联合索引左侧单列] + 通配符在左右两侧

explain select name from test_like where name like '%11%';

bdef9f42917340e85b5e14e0a5a25ebc.png

联合索引,通配符在两侧,select [索引列] 会走索引,type=index,检索性能随索引数据量变大而变差

  • select [联合索引左侧单列] + 通配符在左侧

explain select name from test_like where name like '%11';

f749bf25de5d8ffdc44198f1fb62c70a.png

联合索引,通配符在左侧,select [索引列] 会走索引,type=index,检索性能随索引数据量变大而变差



select 不满足最左匹配原则 - 单列
  • select [联合索引非最左侧单列] + 通配符右侧

explain select age from test_like where name like '11%';

992a6e3038146ecd30074d303aba28b0.png

联合索引,通配符在右侧,select [索引列] 会走索引,type=range,检索性能好

  • select [联合索引非最左侧单列] + 通配符左右两侧

explain select age from test_like where name like '%11%';

64c5ab25b014248f67a7d013ccaa624d.png

联合索引,通配符在两侧,select [索引列] 会走索引,type=ALL,检索性能差

  • select [联合索引非最左侧单列] + 通配符左侧

explain select age from test_like where name like '%11';

a1f4a244a2b31beb1de595ada48abe2c.png

联合索引,通配符在左侧,select [索引列] 会走索引,type=ALL,检索性能差

select 满足最左匹配原则 - 多列索引列(不包含非索引列)
  • select [联合索引多列] + 通配符在右侧

explain select name,age from test_like where name like '11%';

d08e19305ba0b2b274e259d658aae0c1.png

联合索引,通配符在右侧,select [索引列] 会走索引,type=range,检索性能好

  • select [联合索引多列] + 通配符在两侧

explain select name,age from test_like where name like '%11%';

132ff799fedd85027e2205a8ae927151.png

联合索引,通配符在两侧,select [索引列] 会走索引,type=ALL,检索性能差

  • select [联合索引多列] + 通配符在左侧

explain select name,age from test_like where name like '%11';

fada00cea8cc4df1752783e28ece2070.png

联合索引,通配符在左侧,select [索引列] 会走索引,type=ALL,检索性能差


select 满足最左匹配原则 - 多列索引列(包含非索引列)
  • select [联合索引多列+非索引列] + 通配符在右侧

explain select name,age,email from test_like where name like '11%';

a0ed562677e93648a94f16a27d0babb7.png

联合索引,通配符在右侧,select [索引列] 会走索引,type=range,检索性能好

  • select [联合索引多列+非索引列] + 通配符在两侧

explain select name,age,email from test_like where name like '%11%';

16eeb114862d6dd6bd1e73a079544f59.png

联合索引,通配符在两侧,select [索引列] 会走索引,type=ALL,检索性能差

  • select [联合索引多列+非索引列] + 通配符在左侧

explain select name,age,email from test_like where name like '%11';

dadf1ec4664e5d0fa371019e9fee2844.png

联合索引,通配符在左侧,select [索引列] 会走索引,type=ALL,检索性能差


结果说明
  • 联合索引下,检索最左侧单列,无论通配符位置,都会索引覆盖

  • 联合索引下,检索非最左侧单列,只有通配符左侧位置,才会索引覆盖

  • 联合索引下,检索多列索引,无论是否包含非索引列,通配符在右侧时,才会索引覆盖

参考文章

EXPLAIN in SQL:https://www.geeksforgeeks.org/explain-in-sql/

官网Mysql的EXPLAIN信息描述:

https://dev.mysql.com/doc/workbench/en/wb-performance-explain.html

其他文章

SQL性能治理经验谈

理解到位:灾备和只读数据库

记录一次Mysql死锁事件(由Insert与uniqueKey导致)

一文带你看懂:亿级大表垂直拆分的工程实践

亿级大表冷热分级的工程实践

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2113624.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电脑主机内存

在计算机的组成结构当中内存是非常重要的一部分,它用来存储程序和数据。对于计算机来说有了内存才能保证计算机的正常工作。 内部存储器就是我们所说的内存条,一般是用来即时存储数据。不做数据的长期保留。 外部存储器就是我们常说的固态或者硬盘。固态…

电脑点击关机之后,又自动重启开机了。根本就关不了?

前言 有个小姐姐说,她家的电脑好生奇怪:点击【关机】按钮之后,电脑提示【正在关机】,过了几秒,电脑又自动开机了…… 好家伙!也就是说关机和重启根本就没区别,电脑完全无法断电。 最后忍无可…

C++list类介绍和常用接口说明(超全超详细)

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 Clist类介绍和常用接口说明(超全超详细) 收录于专栏【C语法基础】 本专栏旨在分享学习C的一点学习笔记,欢迎大家在评论区交流讨论💌 目录…

推荐一款强大的OCR软件,请低调使用!

今天给大家分享一款开源的OCR识别软件,可以提升大家的办公效率——Umi-OCR,支持window​和Linux系统。 Umi-OCR支持提取一张图片或者多张图片的信息,只需通过右边的功能页选择相应的功能。 点击左边的“截图OCR”进入页面 点击“截图”按钮选…

SpringBoot自定义starter(starter的命名规范、starter的结构、自定义starter、为配置属性添加描述信息、检验配置属性)

文章目录 0. 前言1. 前置知识1.1 starter的命名规范1.2 分析 Mybatis 的场景启动器1.3 starter的结构分析 2. 创建自定义的场景启动器2.1 创建父工程2.2 初始化父工程2.3 创建 autoconfigure 模块2.4 创建 starter 模块2.5 在 starter 模块中引入 autoconfigure 模块的依赖2.6 …

算法学习:滑动窗口

题目 滑动窗口 滑动窗口的题目在解决统计连续带特殊要求的元素串问题时作用巨大。逃离仅仅只是套路学习的黑洞,我认为这种方法在无序的统计中,找到了有序的切入点。初看题目时,可以想到的统计方法有很多,但实现在计算机上则必须有…

我在高职教STM32——准备HAL库工程模板(1)

新学期开学在即,又要给学生上 STM32 嵌入式课程了。这课上了多年了,一直用的都是标准库来开发,已经驾轻就熟了。人就是这样,有了自己熟悉的舒适圈,就很难做出改变,老师上课也是如此,排斥新课和不熟悉的内容。显然,STM32 的开发,HAL 库已是主流,自己其实也在使用,只不…

Mac使用Elasticsearch

下载 Past Releases of Elastic Stack Software | Elastic 解压tar -xzvf elasticsearch-8.15.1-darwin-x86_64.tar.gz 修改配置文件config/elasticsearch.yml xpack.security.enabled: false xpack.security.http.ssl: enabled: false 切换目录 cd elasticsearch-8.15.1/…

Superset二次开发之Select 筛选器源码分析

路径:superset-frontend/src/filters/components/Select 源码文件: 功能点: 作用 交互 功能 index.ts作为模块的入口点,导出其他文件中定义的主要组件和函数。它使其他文件中的导出可以被外部模块使用。 SelectFilterPlugin.tsx 定义主要…

Qt/C++ 个人开源项目#串口助手(源码与发布链接)

一、项目概述 该串口助手工具基于Qt/C开发,专为简化串口通信调试与开发而设计,适合新手快速上手。工具具有直观的用户界面和丰富的功能,旨在帮助用户与串口设备建立可靠通信,便于调试、数据传输和分析。 二、主要功能 波特率&a…

Qt QLineEdit 输入内容后字数在右侧动态展示

前言 QLineEdit 设置可输入最大长度可以使用 lineEdit->setMaxLength(10); 怎么实时的把当前输入字数显示出来呢&#xff0c;像饿了么的 input 组件那样 <el-inputtype"text"placeholder"请输入内容"v-model"text"maxlength"10&q…

基于orangePi的智能家居系统

目录 一.接线图 1.orangePi接线 2.继电器接线 二.语音模块的配置 1.pin脚的配置 2.命令词自定义信息 三.测试 1.通过gpio指令测试烟雾检测器是否正确连接 2.编写脚本测试其他模组接线是否正常 四.人脸识别方案 1.首先开通人脸搜索识别服务 2. 点击产品控制台,向人…

【重学 MySQL】十五、过滤数据

【重学 MySQL】十五、过滤数据 基本用法使用AND、OR和NOT使用IN操作符使用BETWEEN操作符使用LIKE操作符使用IS NULL和IS NOT NULL 在MySQL中&#xff0c;过滤数据主要通过WHERE子句来实现。WHERE子句允许你指定条件来过滤从表中检索出来的行。只有当行满足WHERE子句中的条件时&…

个人随想-一个有意思的鼠标截屏RAG

multi-model rag现在的技术已经比较成熟了&#xff0c;我们也落地了很多公司的rag和agent项目。今天先不说项目落地&#xff0c;今天给大家分享一个有意思的需求。 广州的一家公司&#xff0c;当我们rag搭建完成后&#xff0c;他们的一个产品经理提了一个需求。他们说&#xf…

C#转java工具

使用 激活 点击关闭即可 参考文献 https://www.cnblogs.com/liyhbk/p/17358520.html

【视频教程】手把手AppWizard轻松制作一个emWin滑动主界面控制框架,任意跳转控制(2024-09-06)

现在的新版AppWizard已经比较好用&#xff0c;用户可以轻松的创建各种项目常规界面。 比如早期创建一个支持滑动的主界面框架&#xff0c;并且可以跳转各种子界面&#xff0c;仅仅界面布局和各种图片格式转换都要花不少时间&#xff0c;而现在使用AppWizard&#xff0c;可以说…

关键点检测(7)——yolov8-head的搭建

前两节我学习了yolov8的backbone和head操作。这一节就到了head部分。  我们知道yolov8在流行的yolov5的架构上进行了扩展。在多个方面提供了改进。尤其是head部分&#xff0c;变化最大。yolov8模型与其前身的主要区别在于使用了无锚点检测&#xff08;即从原先的耦合头变成了解…

无人机电调接线

接线方式&#xff1a; 电调的作用是将飞控板的PWM控制信号转变为电流信号 因为电机的电流是很大的&#xff0c;通常每个点击正常工作时都平均有3A左右的电流&#xff0c;如果没有电调的存在&#xff0c;飞控无法承受这么大的电流。 电调的选择&#xff1a;电调上标的电流值是…

240907-Gradio渲染装饰器Render-Decorator

A. 最终效果 B. 示例代码 import gradio as gr import gradio as grwith gr.Blocks() as demo:input_text gr.Textbox()gr.render(inputsinput_text)def show_split(text):if len(text) 0:gr.Markdown("## No Input Provided")else:# for letter in text:for lett…

精通Java微服务

第1章 微服务是在面向服务架构SOA的基础上进一步发展而来的&#xff0c;它比SOA做得更加彻底&#xff0c;其单体服务被更加彻底地划分&#xff0c;最大限度地实现了服务的单一职责。 1.1.2互联网 即计算机网络&#xff0c;连接了世界上数以万计的计算机设备&#xff08;可联…