MySQL索引原理以及SQL优化

案例

struct index_failure_t{int id;string name;int cid;int score;string phonenumber;}Map<int,index_failure>;

熟悉C++的同学知道,上述案例中,我们map底层是一颗红黑树,一个节点存储了一对kv(键值对),k是int类型,v是结构体类型。我们把大量的数据记录到这颗红黑树中。

对应到sql中,语法变成了

CREATE TABLE ‘index_failure_t’(‘id’ INT(11) NOT NULL AUTO_INCREAMENT,‘name’ VARCHAR(255) DEFAULT NULL,‘cid’ INT(11) DEFAULT NULL,‘score’ SAMLLINT DEFAULT 0,‘phonenumber’ VARCHAR(20),PRIMARY KEY(‘id’),)

其中PRIMARY KEY(‘id’)相当于C++案例中的map指定KEY的步骤。存储结构也由红黑树变成了B+树。

如果在其中再添加 KEY ‘name_idx‘ (‘name’)语句,在C++中相当于再建立Map<string,int>。如果要搜寻某些数据,则通过Map<string,int>获取到int,再根据这个int获取Map<int,index_failure>里的数据,这种做法叫做“回表查询”。这里的索引也叫二级索引或者辅助索引。

细节上有所差异,业务上高度相似。红黑树是二叉平衡搜索树,B+树是多路平衡搜索树。

Sql中的索引简介

索引,在sql底层的B+树中,就是各个节点的key。通过索引,可以快速地锁定数据的位置。

主键索引

它是非空唯一索引,一个表只有一个主键索引;在 innodb 中,主键索引的 B+ 树包含表数据信息。如果没有执行主键索引,那么会自动把第一个非空唯一索引设为主键,如果没有非空唯一索引,那么自动生成一个主键索引rowid。

PRIMARY KEY(key1, key2)

唯一索引

不可以出现相同的值,可以有 NULL 值;

UNIQUE(key)

普通索引

允许出现相同的索引内容;

INDEX(key) OR KEY(key[,...])

组合索引

对表上的多个列进行索引

索引代价

代价:占用空间,DML语句变慢(因为底层维护的数据结构变多了)。

索引的使用场景

B+树和红黑树

B+树:多路平衡搜索树

红黑树:二叉平衡搜索树

多路:一个节点可以有多个子节点。

二叉:一个节点只能由2个子节点。

平衡:平衡根节点到各个叶子节点的高度,提供稳定是时间搜索复杂度。

搜索树:是有序的树结构。

B+树并不是一个节点存储一条数据,而是一个节点存储16kb数据,叶子节点存储数据库数据,非叶子节点存储地址数据。这样做的目的是让B+树尽量是矮胖结构,减少磁盘IO的次数,因为每走到一个节点都要把节点的数据内容加载到内存中,进行一次磁盘IO,磁盘IO的耗时是内存IO的百倍。

B树则非叶子节点也存储数据信息。

innodb 体系结构

Buffer Pool主要用于缓存聚集索引和二级索引的B+树节点,也就是热门数据。

Change Buffer则专门用于缓存对聚集索引的修改操作。这些数据并不在 buffer pool 中,Change buffer 中的数据将会异步 merge 到 buffer pool 中。

Buffer Pool修改的数据会不经过内核的高速缓冲区,直接通过O_DIRECT刷入磁盘中。

SQL查询优化涉及原则及思路

EXPLAIN查询sql优化器方案

EXPLAIN是一个关键字,用于查询优化器解析和显示查询执行计划。

MySQL会解析查询,并返回一张执行计划表,该表描述了查询执行的步骤和顺序。执行计划表的列包括:

id:每个查询块(query block)的唯一标识符。

select_type:查询类型,例如SIMPLE(简单查询)、PRIMARY(主查询)等。

table:查询涉及的表名。

partitions:查询涉及的分区。

type:连接类型,例如ALL(全表扫描,尽量不要出现)、INDEX(索引扫描)、ref(索引值不好说、可能是非唯一索引)。

possible_keys:可能使用的索引。

key:实际使用的索引。

key_len:使用的索引的长度。

ref:连接条件,例如const(无需访问它表)。

rows:估计的返回行数。

filtered:过滤后的行百分比。

Extra:其他的附加信息。

覆盖索引

其实叫做索引覆盖更加合理,就是在辅助索引B+树里能找到全部所需数据,就不再进行回表查询了,可以减少查询耗时。这时候要求我们select语句尽量能包含辅助索引B+树的数据,而不是用select *。

最左匹配原则

最左匹配原则只适用于使用组合索引的情况,对于单列索引或者没有索引的情况,顺序并不重要。当查询语句中有多个条件,并且这些条件可以利用索引进行匹配时,最左匹配原则决定了如何使用索引进行匹配。我们可以通过利用最左匹配规则的思路,减少B+树的创建数量,也就是过度索引,比如一棵树虽然有组合索引,但是我们可以通过最左匹配规则只沿用其中一条索引也能起到相同的效果。同时组合索引的存在也能帮助我们复用索引减少回表次数。

索引下推

索引存储

索引失效

select ... where A and B 若 A 和 B 中有一个不包含索引,则索引失效;

索引字段参与运算,则索引失效;例如:from_unixtime(idx)= '2021-04-30'; 改成 idx = unix_timestamp("2021-04-30");

索引字段发生隐式转换,则索引失效;例如:将列隐式转换为某个类型,实际等价于在索引列上作用了隐式转换函数;

LIKE 模糊查询,通配符 % 开头,则索引失效;例如:select* from user where name like '%Mark';

在索引字段上使用 【NOT】【 <>】【 != 】索引失效;如果判断 id <> 0则修改为idx > 0 or idx < 0;

组合索引中,没使用第一列索引,索引失效;

Sql查询优化思路

查询频次较高且数据量大的表建立索引;

索引选择使用频次较高,过滤效果好的列或者组合;

使用短索引,能使得节点包含的信息多,较少磁盘 IO 操作;比如: smallint,tinyint;

对于组合索引,考虑最左侧匹配原则和覆盖索引;

尽量选择区分度高的列作为索引,该列的值相同的越少越好;

尽量扩展索引,在现有索引的基础上,添加复合索引;最多 6 个 索引;

不要 select *; 尽量只列出需要的列字段;方便使用覆盖索 引;

索引列,列尽量设置为非空;

可选:开启自适应 hash 索引或者调整 change buffer;

Sql查询优化方法

Show processlist:是一个用于查看当前正在运行的数据库连接和查询的 MySQL 命令。它会返回一个结果集,该结果集包含了当前活动的数据库连接的详细信息。通过查看 SHOW PROCESSLIST 的结果,你可以了解当前正在运行的查询、连接的用户、连接的状态以及查询执行的时间。这对于监视数据库的性能、识别慢查询或长时间运行的查询以及查找可能存在的连接问题都非常有用。

慢查询日志:慢查询是指执行时间较长的查询语句,可能会对数据库性能产生负面影响。通过开启慢日志,数据库会将执行时间超过设定阈值的查询语句记录到慢日志文件中,以便后续分析和优化。

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

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

相关文章

seata 分布式

一、下载安装seata 已经下载好的朋友可以跳过这个步骤。这里下载的是seata1.6.1这个版本。 1、进入seata官网 地址&#xff1a; https://seata.io/zh-cn/index.html 2、进入下载 3、点击下载地址 下载地址&#xff1a; https://github.com/seata/seata 二、配置seata 进入c…

git仓库批量备份

git的mirror参数 在git中&#xff0c;--mirror是一个用于克隆和推送操作的参数。它用于创建一个镜像仓库&#xff0c;包含了源仓库的所有分支、标签和提交历史记录。 当使用git clone --mirror <source-repo>命令时&#xff0c;会创建一个完全相同的镜像仓库&#xff0…

虚拟机设置静态ip

有时候搭环境需要局域网&#xff0c;设置一下虚拟机静态ip&#xff0c;这里做个记录&#xff1a; 这里我用的是ubuntu18.04的虚拟机&#xff0c;安装完成之后&#xff0c;点击进入设置 这里设置一下桥接模式 这个时候输入ifconfig&#xff0c;就是和主机一个网段了&#xff…

跟着cherno手搓游戏引擎【14】封装opengl

本节先把代码粘上&#xff0c;后续会慢慢把注释都给加上&#xff0c;先看代码了解个大概&#xff08;待更新&#xff09; 前置&#xff1a; RendererAPI.h: #pragma once namespace YOTO {enum class RendererAPI {None 0,OpenGL1};class Renderer {public:inline static R…

JavaWeb后端登录校验功能(JWT令牌技术,Cookie技术,Session,拦截技术,过滤器)

目录 一.登录校验功能&#xff08;解决直接通过路径访问&#xff09; 1.实现思路 二.会话技术 ​编辑 1.Cookie技术 2.Session 3.令牌技术 1.简介 2.如何生成和解析 3.令牌的使用 三.Filter过滤器 1.什么是过滤器 2.实现步骤&#xff1a; 3.过滤器执行流程 4.拦截路径 5.过…

[C++历练之路]C++中的继承小学问

W...Y的主页 &#x1f60a; 代码仓库分享&#x1f495; &#x1f354;前言&#xff1a; C中&#xff0c;继承是一种面向对象编程的重要概念&#xff0c;它允许一个类&#xff08;子类/派生类&#xff09;从另一个类&#xff08;父类/基类&#xff09;继承属性和方法。继承是…

Hadoop-MapReduce-YarnChild启动篇

一、源码下载 下面是hadoop官方源码下载地址&#xff0c;我下载的是hadoop-3.2.4&#xff0c;那就一起来看下吧 Index of /dist/hadoop/core 二、上下文 在上一篇<Hadoop-MapReduce-MRAppMaster启动篇>中已经将到&#xff1a;MRAppMaster的启动&#xff0c;那么运行M…

(刷题记录)移除元素

我的代码&#xff1a; class Solution {public int removeElement(int[] nums, int val) {int j0;for(int i0;i<nums.length;i){if(nums[i]!val){nums[j]nums[i];j;}}return j;} }思路&#xff1a;双指针&#xff0c;右指针指向当前要处理的元素&#xff0c;有不等的数就赋…

Docker私有仓库搭建

registry私有仓库 步骤一&#xff1a;先拉取registry的镜像 [rootlocalhost ~]#docker pull registry 步骤二&#xff1a;修改docker的配置文件重启 [rootlocalhost ~]#vim /etc/docker/daemon.json {"insecure-registries": ["192.168.66.66:5000"] }[r…

浅谈隔离放大器

浅谈隔离放大器 定义&#xff1a;隔离放大器是将输入的电量信号或物理量信号通过一种技术手段处理后,隔离输出一组模拟量信号,这组模拟量信号是以标准的4-20mA/0-20mA/0-10mA/0-10V/0-5V/1-5V/2-10V/0-2.5V/0-20mA/0-10mA/0-10V/0-100mV/0-5V等信号,以便控制系统及仪器仪表设备…

PGsql 解析json及json数组

创建测试数据 drop table if exists json_test; create table json_test as select 111 as id, {"nodes":{"1692328028076":{"nodeId":"1692328028076","nodeName":"测试表1","nodeType":"DATACO…

单片机学习笔记---定时器计数器(含寄存器)工作原理介绍(详解篇2)

目录 T1工作在方式2时 T0工作在方式3时 四种工作方式的总结 定时计数器对输入信号的要求 定时计数器对的编程的一个要求 关于初值计算的问题 4种工作方式的最大定时时间的大小 关于编程方式的问题 实例分析 实例1 实例2 T1工作在方式2时 51单片机&#xff0c;有两个…

vue实践:构建高效的电子签名功能

前言 在现代数字化时代&#xff0c;电子签名成为了一种方便、高效且安全的签署文件的方式。本文将介绍电子签名的原理和实现方法&#xff0c;帮助你快速掌握这一重要的工具。 电子签名是什么&#xff1f; 电子签名是一种数字化的签名方式&#xff0c;用于验证和确认电子文档、…

matlab appdesigner系列-app程序打包成可执行exe程序

提供了3种打包方式&#xff1a; 1&#xff09;Matlab App &#xff0c;这种方式是生成Matlab内部使用的小程序&#xff0c;可添加到matlab app菜单栏中的常用程序中&#xff0c;也就是应用该程序之前&#xff0c;你必须安装了matlab&#xff1b; 2&#xff09;Web app 3&…

vs 撤销本地 commit 并保留更改

没想到特别好的办法&#xff0c;我想的是用 vs 打开 git 命令行工具 然后通过 git 命令来撤销提交&#xff0c;尝试之前建议先建个分支实验&#xff0c;以免丢失代码&#xff0c; git 操作见 git 合并多个 commit / 修改上一次 commit

2024.1.29 GNSS 学习笔记

1.假设只对4颗卫星进行观测定位&#xff0c;卫星的截止高度角是15&#xff0c;那么如何布设这四颗卫星的位置&#xff0c;使其围成的四面体的体积得到最大&#xff0c;以获得最好定位精度&#xff1f; 答&#xff1a;3颗卫星均匀分布在最低仰角面上&#xff0c;第4颗卫星在测站…

华为笔记本matebook pro X如何扩容 C 盘空间

一、前提条件 磁盘扩展与合并必须是相邻分区空间&#xff0c;且两个磁盘类型需要相同。以磁盘分区为 C 盘和 D 盘为例&#xff0c;如果您希望增加 C 盘容量&#xff0c;可以先将 D 盘合并到 C 盘&#xff0c;然后重新创建磁盘分区&#xff0c;分配 C 盘和 D 盘的空间大小。 访…

git push后,如何撤销git log上的错误注释

修改了本地的代码&#xff0c;执行了下面的操作&#xff0c;提交之后&#xff0c;怎么样修改 git add ********(文件名)//git add 添加修改文件名之后 git commit //git commit 在当前分支提交&#xff0c;编写提交注释 git push //git push 提交修…

Android T 远程动画显示流程(更新中)

序 本地动画和远程动画区别是什么? 本地动画&#xff1a;自给自足。对自身SurfaceControl矢量动画进行控制。 远程动画&#xff1a;拿来吧你&#xff01;一个app A对另一个app B通过binder跨进程通信&#xff0c;控制app B的SurfaceControl矢量动画。 无论是本地动画还是远程…

C++ Qt开发:运用QJSON模块解析数据

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍如何运用QJson组件的实现对JSON文本的灵活解析…