MySQL查询性能优化之索引覆盖、索引下推、索引潜水、索引合并

news2024/12/23 18:19:17

索引覆盖

什么是索引覆盖

select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖。

如何实现索引覆盖?

最常见的方法就是:将被查询的字段,建立到联合索引(如果只有一个字段,普通索引也可以)里去。

例如建立如下表:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `surname` varchar(2) NOT NULL DEFAULT '' COMMENT '姓',
  `name` varchar(10) NOT NULL DEFAULT '' COMMENT '名',
  `full_name` varchar(12) GENERATED ALWAYS AS (concat(`surname`,`name`)) STORED COMMENT '全名',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  `sex` varchar(2) DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`),
  KEY `idx_age_sex` (`age`,`sex`)
) ENGINE=InnoDB AUTO_INCREMENT=1144780 DEFAULT CHARSET=utf8mb4

在这里插入图片描述
当查询所有字段时,需要使用了索引,但是还需要回表获取所有的行数据。
在这里插入图片描述
当查询只有age、sex时,explain 的Extra为Using index表示使用了索引覆盖。

索引下推

什么是所有下推?

索引下推(Index Condition Pushdown,简称ICP),是MySQL5.6版本的新特性,它能减少回表查询次数,提高查询效率。

索引下推有哪些作用?

主要作用有两个:

  1. 减少回表查询的次数
  2. 减少存储引擎和MySQL Server层的数据传输量

索引下推配置

查看索引下推的配置:

show variables like '%optimizer_switch%';

如果输出结果中,显示 index_condition_pushdown=on,表示开启了索引下推。
在这里插入图片描述

开启索引下推

开启索引下推:

set optimizer_switch="index_condition_pushdown=on";

关闭索引下推

关闭索引下推:

set optimizer_switch="index_condition_pushdown=off";

索引下推原理

创建实战数据表:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `surname` varchar(2) NOT NULL DEFAULT '' COMMENT '姓',
  `name` varchar(10) NOT NULL DEFAULT '' COMMENT '名',
  `full_name` varchar(12) GENERATED ALWAYS AS (concat(`surname`,`name`)) STORED COMMENT '全名',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  `sex` varchar(2) DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`),
  KEY `idx_age_sex` (`age`,`sex`)
) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8mb4

在age、sex列上建立联合索引。

在没有使用索引下推的情况,查询过程是这样的:

  1. 存储引擎根据where条件中age索引字段,找到符合条件行主键ID
  2. 然后二次回表查询,根据主键ID去主键索引上找到整行记录
  3. 把数据返回给MySQL Server层,再根据where中sex条件,筛选出符合要求的一行记录
  4. 返回给客户端

在使用索引下推的情况,查询过程是这样的:

  1. 存储引擎根据where条件中age索引字段,找到符合条件的行记录,再用sex条件筛选出符合条件主键ID
  2. 然后二次回表查询,根据主键ID去主键索引上找到该整行记录
  3. 把数据返回给MySQL Server层
  4. 返回给客户端
    在这里插入图片描述
    执行计划中的Extra列显示了Using index condition,表示用到了索引下推的优化逻辑。

索引下推应用范围

  1. 适用于InnoDB 引擎和 MyISAM 引擎的查询
  2. 适用于执行计划是range, ref, eq_ref, ref_or_null的范围查询
  3. 对于InnoDB表,仅用于非聚簇索引。索引下推的目标是减少全行读取次数,从而减少 I/O 操作。对于 InnoDB聚集索引,完整的记录已经读入InnoDB 缓冲区。在这种情况下使用索引下推 不会减少 I/O。
  4. 子查询不能使用索引下推
  5. 存储过程不能使用索引下推

索引潜水

什么是索引潜水?

先看下实际操作。
创建表:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `surname` varchar(2) NOT NULL DEFAULT '' COMMENT '姓',
  `name` varchar(10) NOT NULL DEFAULT '' COMMENT '名',
  `full_name` varchar(12) GENERATED ALWAYS AS (concat(`surname`,`name`)) STORED COMMENT '全名',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  `sex` varchar(2) DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`),
  KEY `idx_age_sex` (`age`,`sex`)
) ENGINE=InnoDB AUTO_INCREMENT=151 DEFAULT CHARSET=utf8mb4

往里面写入128行数据:

select count(id) from user;

在这里插入图片描述
执行in操作:
在这里插入图片描述
在这里插入图片描述
同样是in的查询,参数数量不一样时,rows和type都不一样。

in参数数量决定了走索引潜水还是索引统计的方式。

索引潜水有哪些作用?

都用索引潜水(Index dive)的方式预估扫描行数,不好吗?

其实这是基于成本的考虑索引潜水估算成本较高,适合小数据量。索引统计估算成本较低,适合大数据量。

一般情况下,我们的where语句的in条件的参数不会太多,适合使用索引潜水预估扫描行数。

建议还在使用MySQL5.7.3之前版本的同学们,手动修改一下索引潜水的配置参数,改成合适的数值。

索引潜水配置

查询配置:

show variables like '%eq_range_index_dive_limit%';

在这里插入图片描述
eq_range_index_dive_limit 配置的作用就是:
当where语句in条件中参数个数小于这个值的时候,MySQL就采用索引潜水(Index dive)的方式预估扫描行数,非常准确。

当where语句in条件中参数个数大于等于这个值的时候,MySQL就采用另一种方式索引统计(Index statistics)预估扫描行数,误差较大。

修改配置:

set eq_range_index_dive_limit=200;

索引合并

什么是索引合并?

当单表存在多个索引,一个SQL语句的where中又含有多个索引字段,在执行SQL语句时每个索引都可能返回一个结果集,MySQL会将其求交集或者并集,或者是交集和并集的组合。也就是说一次查询中可以使用多个索引。

我们创建一个表:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `surname` varchar(2) NOT NULL DEFAULT '' COMMENT '姓',
  `name` varchar(10) NOT NULL DEFAULT '' COMMENT '名',
  `full_name` varchar(12) GENERATED ALWAYS AS (concat(`surname`,`name`)) STORED COMMENT '全名',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  `sex` varchar(2) DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`),
  KEY `idx_age_sex` (`age`,`sex`)
) ENGINE=InnoDB AUTO_INCREMENT=151 DEFAULT CHARSET=utf8mb4

在age、sex列建立联合索引,在name建立索引。

执行查询时:
在这里插入图片描述
在使用explain 时,在type那一列会显示index_merge,key那一列是所有使用到的索引。

索引合并又包含三个算法,在explain中显示:

  1. using intersect
    index merge intersection access algorithm(索引合并交集访问算法)。
    对于每一个使用到的索引进行查询,查询主键值集合,然后进行合并,求交集,也就是AND运算。

  2. using union
    index merge union access algorithm(索引合并并集访问算法)
    容易看出,与上述的算法类似,不过是使用了or连接条件,求并集。
    执行流程与index merge intersect 类似,依旧是查询了有序的主键集合,然后进行求并集。

  3. using sort_union
    index merge sort sort-union access algorithm (索引合并排序并集访问算法)
    根据索引查询得到主键集合,对于每个主键集合进行排序,然后求并集。

索引合并有哪些作用?

索引合并能使用多个索引,提高查询的速度。

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

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

相关文章

python---变量(2)

此处,首次使用“”对a进行设置值,也就是对a的初始化。 后续位置对a使用“”,实际上是对a赋值。 因此两行代码得到的结果显然是不同的! 变量的种类 1.整数-int-根据数据大小自动扩容 python中的变量类型不需要显示声明&#…

关于 arduino 中的 constrain(x, a, b)函数

当我们需要将一个变量的值限制在某个范围内时,可以使用 constrain(x, a, b) 函数来实现。该函数可以将参数 x 的值限制在区间 [a, b] 之间,如果 x 小于 a,则返回 a,如果 x 大于 b,则返回 b,否则返回 x。下面…

第五篇、基于Arduino uno,获取超声波(HC04)传感器的距离数据——结果导向

0、结果 说明:先来看看串口调试助手显示的结果,显示的是一个距离值,如果是你想要的,可以接着往下看。 1、外观 说明:虽然超声波传感器形态各异,但是原理和代码都是适用的。 2、连线 说明:只…

材料力学-剪力和弯矩方向规定及关系

剪力和弯矩的方向规定方法 对水平梁的某一指定截面来说, 剪力:在它左侧的向上外力,或右侧的向下外力,将产生正的剪力;反之,即产生负的剪力。 自己的记法(可以不按我的来)&#xff1…

ChatGPT:你真的了解网络安全吗?浅谈网络安全攻击防御进行时之网络安全新总结

ChatGPT:你真的了解网络安全吗?浅谈网络安全攻击防御进行时 网络安全新总结 ChatGPT(全名:Chat Generative Pre-trained Transformer),美国OpenAI 研发的聊天机器人程序,是人工智能技术驱动的自…

ChatGPT在数据分析中的应用

最近,机器学习和人工智能技术在数据分析领域中发挥着越来越大的作用。而chatgpt正是这个领域最受欢迎的仿人聊天 AI 。但是,对于许多数据科学家和分析师来说,chatgpt并不是他们首选的工具。相反,pandas、sk-learn是数据科学家的最…

一起来聊聊ERP

聊聊ERP 哈喽,哈喽,大家好!今天开始,我们就来讲ERP了。 什么是ERP ERP是Enterprise Resource Planning 的缩写,中文含义是企业资源计划。它代表了当前在全球范围内应用最广泛、最有效的一种企业管理方法,…

JVM系列-第12章-垃圾回收器

垃圾回收器 GC 分类与性能指标 垃圾回收器概述 垃圾收集器没有在规范中进行过多的规定,可以由不同的厂商、不同版本的JVM来实现。 由于JDK的版本处于高速迭代过程中,因此Java发展至今已经衍生了众多的GC版本。 从不同角度分析垃圾收集器,…

gym不渲染画面的解决方案(gym版本号0.26.2)

确认gym版本号 我安装了新版gym,版本号是0.26.2,不渲染画面的原因是,新版gym需要在初始化env时新增一个实参render_mode‘human’,并且不需要主动调用render方法,官方文档入门教程如下 import gym import numpy as n…

FreeRTOS学习之路,以STM32F103C8T6为实验MCU(第一章——FreeRTOS的基本框架)

学习之路主要为FreeRTOS操作系统在STM32F103(STM32F103C8T6)上的运用,采用的是标准库编程的方式,使用的IDE为KEIL5。 注意!!!本学习之路可以通过购买STM32最小系统板以及部分配件的方式进行学习…

day15 Servlet-Request-Response

请求对象(request) **请求对象的作用:**封装了所有请求的数据,有服务器实现这个对象,我们直接调用sercive()方法 HttpServletRequest对象的常用方法 request请求方法描述request.getMethod()获得请求方式post\getre…

基于SpringBoot+Uniapp的微信小程序二手购物商城(用户手册+测试报告+详细设计文档)

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背景介绍: 这个微信小程序二手购…

LangChain使用调研

目录 一、LangChain是什么 二、LangChain提供的主要模块 三、Agent使用例子 四、zero-shot-react-description在ChatGPT和LLaMA-7B效果对比 一、LangChain是什么 LangChain是一个程序框架,它允许用户围绕LLM(基座)快速构建应用程序。 La…

多维时序 | MATLAB实现GA-BiLSTM遗传算法优化双向长短期记忆网络的多变量时间序列预测

多维时序 | MATLAB实现GA-BiLSTM遗传算法优化双向长短期记忆网络的多变量时间序列预测 目录 多维时序 | MATLAB实现GA-BiLSTM遗传算法优化双向长短期记忆网络的多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 MATLAB实现GA-BiLSTM遗传算法优化双向长短…

宏工科技“全面”发力CIBF,助推电池智造“高效提质”

5月16-18日,第十五届中国国际电池技术展览会(CIBF2023)在深圳盛大举行。宏工科技携电池材料与电池匀浆领域的创新产品和系统解决方案精彩亮相。 据了解,宏工科技在新能源行业的业务涉及电池材料整线产线、电池匀浆、电池回收三个…

边沿检测电路

目录 同步信号的边沿检测 异步信号的边沿检测 所谓的边沿检测(幼教边沿提取),就是检测输入信号的上升沿和下降沿。在设计数字系统时,边沿检测是一种很重要的思想,实际编程时用的最多的时序电路应该就是边沿检测电路和…

为什么要把一个函数分解成三角函数?(傅利叶级数)

为什么要把一个函数分解成三角函数?(傅利叶级数) 笔记来源:【知识拼图】傅里叶变换从零到一 02集 傅里叶级数从起源到操作,真的很细 把一个函数分解成三角级数体现了化繁为简,一个复杂函数化成许多三角函数的叠加 先回顾一下向量…

CyberLink的颜色修正和调整软件ColorDirector Ultra 11.0版本在win10系统的下载与安装配置教程

目录 前言一、ColorDirector Ultra安装二、使用配置总结 前言 ColorDirector Ultra是由CyberLink公司开发的一款专业的颜色修正和调整工具,可以帮助用户实现对视频中颜色的全方位管理。该软件支持对各种分辨率的视频进行颜色调整,并且可以从各种设备&am…

第四篇、基于Arduino uno,获取土壤湿度传感器的原始值和含水量——结果导向

0、结果 说明:先来看看串口调试助手显示的结果,第一个值是原始的模拟电压值,第二个值是含水量,如果是你想要的,可以接着往下看。 1、外观 说明:虽然土壤湿度传感器形态各异,但是原理和代码都是…

( 数组) 27. 移除元素 ——【Leetcode每日一题】

❓27. 移除元素 难度:简单 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。 不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以…