【Mysql】事务与索引

目录

MySQL事务

事务的特性

并发事务的问题?

事务隔离级别?

MySQL索引

数据结构

索引类型

聚簇索引与非聚簇索引

聚集索引的优点

聚集索引的缺点

非聚集索引的优点

非聚集索引的缺点

非聚集索引一定回表查询吗(覆盖索引)?

覆盖索引

联合索引

最左前缀匹配原则

创建索引的注意事项

什么时候别用索引?

索引优化

索引失效


MySQL事务

定义:多条sql语句,要么全部成功,要么全部失败。

事务的特性

数据库事务特性:原子性(Atomic)、一致性(Consistency)、隔离性(Isolation)、持久性(Durabiliy)。简称ACID

  • 原子性:组成一个事务的多个数据库操作不可分割,只有所有操作都成功,整个事务才会提交。任何一个操作失败,已经执行的任何操作都必须撤销,让数据库返回初始状态。

  • 一致性:事务操作成功后,数据库所处的状态和它的业务规则是一致的。即数据不会被破坏。如A转账100元给B,不管操作是否成功,A和B的账户总额是不变的。

  • 隔离性:在并发数据操作时,不同的事务拥有各自的数据空间,它们的操作不会对彼此产生干扰

  • 持久性:一旦事务提交成功,事务中的所有操作都必须持久化到数据库中。

并发事务的问题?
  • 脏读: 如果一个事务「读到」了另一个「未提交事务修改过的数据」,就意味着发生了「脏读」现象。

  • 丢失修改: 指在一个事务读取一个数据时,另外一个事务也访问了该数据,那么在第一个事务中修改了这个数据后,第二个事务也修改了这个数据。这样第一个事务内的修改结果就被丢失,因此称为丢失修改。

    • 例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。

  • 不可重复读: 指在一个事务内多次读同一数据,在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就造成在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。

  • 幻读: 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。

不可重复读和幻读区别:

不可重复读的重点是修改,幻读的重点在于新增或者删除

事务隔离级别?

SQL 标准定义了四个隔离级别:

  • (读未提交): 最低的隔离级别,允许读取尚未提交的数据,可能会导致脏读、幻读或不可重复读。

  • (读已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。

  • (可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

  • (可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

隔离级别脏读不可重复读幻读
读未提交
读取已提交×
可重复读××
可串行化×××

MySQL的默认隔离级别是可重复读

MySQL索引

索引是一种用于快速查询和检索数据的数据结构,其本质可以看成是一种排序好的数据结构。

优点

  • 使用索引可以大大加快数据的检索速度(大大减少检索的数据量), 这也是创建索引的最主要的原因。

  • 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

缺点

  • 创建索引和维护索引需要耗费许多时间。当对表中的数据进行增删改的时候,如果数据有索引,那么索引也需要动态的修改,会降低 SQL 执行效率。

  • 索引需要使用物理文件存储,也会耗费一定空间。

数据结构
  • Hash表

    哈希表是键值对的集合,通过键(key)即可快速取出对应的值(value),因此哈希表可以快速检索数据,接近 O(1)。

    为什么MySQL 没用它?

    1.Hash 冲突问题 :我们上面也提到过Hash 冲突了,不过对于数据库来说这还不算最大的缺点。

    2.Hash 索引不支持顺序和范围查询,这是它最大的缺点: 假如我们要对表中的数据进行排序或者进行范围查询,那 Hash 索引可就不行了。

  • B & B+

    B 树& B+树两者有何异同呢?

    • B 树的所有节点既存放键(key) 也存放 数据(data),而 B+树只有叶子节点存放 key 和 data,其他内节点只存放 key。

    • B 树的叶子节点都是独立的;B+树的叶子节点有一条引用链指向与它相邻的叶子节点。

    • B 树的检索的过程相当于对范围内的每个节点的关键字做二分查找,可能还没有到达叶子节点,检索就结束了。而 B+树的检索效率就很稳定了,任何查找都是从根节点到叶子节点的过程,叶子节点的顺序检索很明显。

索引类型
  • 主键索引 : 数据表的主键列使用的就是主键索引

  • 二级索引(辅助索引) : 因为二级索引的叶子节点存储的数据是主键。也就是说,通过二级索引,可以定位主键的位置。

    • 唯一索引 :唯一索引也是一种约束。唯一索引的属性列不能出现重复的数据,但是允许数据为 NULL,一张表允许创建多个唯一索引。 建立唯一索引的目的大部分时候都是为了该属性列的数据的唯一性,而不是为了查询效率。

    • 普通索引普通索引的唯一作用就是为了快速查询数据,一张表允许创建多个普通索引,并允许数据重复和 NULL。

    • 前缀索引 :前缀索引只适用于字符串类型的数据。前缀索引是对文本的前几个字符创建索引,相比普通索引建立的数据更小, 因为只取前几个字符。

    • 全文索引 :全文索引主要是为了检索大文本数据中的关键字的信息,是目前搜索引擎数据库使用的一种技术。Mysql5.6 之前只有 MYISAM 引擎支持全文索引,5.6 之后 InnoDB 也支持了全文索引。

聚簇索引与非聚簇索引

聚集索引就是索引结构和数据一起存放的索引。主键索引属于聚集索引。

聚集索引的优点

聚集索引的查询速度非常的快,因为整个 B+树本身就是一颗多叉平衡树,叶子节点也都是有序的,定位到索引的节点,就相当于定位到了数据。

聚集索引的缺点
  1. 依赖于有序的数据 :因为 B+树是多路平衡树,如果索引的数据不是有序的,那么就需要在插入时排序,如果数据是整型还好,否则类似于字符串或 UUID 这种又长又难比较的数据,插入或查找的速度肯定比较慢。

  2. 更新代价大 : 如果对索引列的数据被修改时,那么对应的索引也将会被修改,而且聚集索引的叶子节点还存放着数据,修改代价肯定是较大的,所以对于主键索引来说,主键一般都是不可被修改的

非聚集索引即索引结构和数据分开存放的索引 , 二级索引属于非聚集索引。

非聚集索引的叶子节点并不一定存放数据的指针,因为二级索引的叶子节点就存放的是主键,根据主键再回表查数据。

非聚集索引的优点
  • 更新代价比聚集索引要小

非聚集索引的缺点
  1. 跟聚集索引一样,非聚集索引也依赖于有序的数据

  2. 可能会二次查询(回表) :这应该是非聚集索引最大的缺点了。 当查到索引对应的指针或主键后,可能还需要根据指针或主键再到数据文件或表中查询。

非聚集索引一定回表查询吗(覆盖索引)?

非聚集索引不一定回表查询。

主键索引本身的 key 就是主键,查到返回就行了。这种情况就称之为覆盖索引了。

例如 : SELECT id FROM table WHERE id=1;

覆盖索引

覆盖索引就是说需要查询的字段正好是索引的字段,那么直接根据该索引,就可以查到数据了, 而无需回表查询。

联合索引

使用表中的多个字段创建索引,就是 联合索引,也叫 组合索引复合索引

最左前缀匹配原则

最左前缀匹配原则指的是,在使用联合索引时,MySQL 会根据联合索引中的字段顺序,从左到右依次到查询条件中去匹配,如果查询条件中存在与联合索引中最左侧字段相匹配的字段,则就会使用该字段过滤一批数据,直至联合索引中全部字段匹配完成,或者在执行过程中遇到范围查询(如 ><)才会停止匹配。对于 >=<=BETWEENlike 前缀匹配的范围查询,并不会停止匹配。所以,我们在使用联合索引时,可以将区分度高的字段放在最左边,这也可以过滤更多数据。

创建索引的注意事项
  • 选择合适的字段

    • 不为NULL的字段 , 如果需要 , 使用0 , 1 , true , false来代替

    • 被频繁查询的字段

    • 被作为条件查询的字段

    • 频繁需要排序的字段

    • 频繁连接的字段

  • 被频繁更新的字段应谨慎建立索引

  • 尽量考虑联合索引而非单列索引

  • 尽量避免冗余索引

    • 能够命中索引(a, b)就肯定能命中索引(a) ,那么索引(a)就是冗余索引

什么时候别用索引?
  1. 经常增删改的列不要建立索引;

  2. 有大量重复的列不建立索引;

  3. 表记录太少不要建立索引

索引优化
  • 前缀索引优化;

    • 前缀索引顾名思义就是使用某个字段中字符串的前几个字符建立索引,那为什么需要使用前缀来建立索引呢?

      使用前缀索引是为了减小索引字段大小,可以增加一个索引页中存储的索引值,有效提高索引的查询速度。在一些大字符串的字段作为索引时,使用前缀索引可以帮助我们减小索引项的大小。

  • 覆盖索引优化;

    • 覆盖索引是指 SQL 中 query 的所有字段,在索引 B+Tree 的叶子节点上都能找得到的那些索引,从二级索引中查询得到记录,而不需要通过聚簇索引查询获得,可以避免回表的操作。

  • 主键索引最好是自增的;

    • 如果我们使用自增主键,那么每次插入的新数据就会按顺序添加到当前索引节点的位置,不需要移动已有的数据,当页面写满,就会自动开辟一个新页面。因为每次插入一条新记录,都是追加操作,不需要重新移动数据,因此这种插入数据的方法效率非常高。

      如果我们使用非自增主键,由于每次插入主键的索引值都是随机的,因此每次插入新的数据时,就可能会插入到现有数据页中间的某个位置,这将不得不移动其它数据来满足新数据的插入,甚至需要从一个页面复制数据到另外一个页面,我们通常将这种情况称为页分裂页分裂还有可能会造成大量的内存碎片,导致索引结构不紧凑,从而影响查询效率

  • 防止索引失效;

    • 发生索引失效的情况:

      • 当我们使用左或者左右模糊匹配的时候,也就是 like %xx 或者 like %xx%这两种方式都会造成索引失效;

      • 当我们在查询条件中对索引列做了计算、函数、类型转换操作,这些情况下都会造成索引失效;

      • 联合索引要能正确使用需要遵循最左匹配原则,也就是按照最左优先的方式进行索引的匹配,否则就会导致索引失效。

      • 在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列,那么索引会失效。

索引失效

1、使用!= 或 <>

2、最左前缀原则

3、字段类型不一致索引失效

4、函数导致索引失效

5、运算符导致索引失效

如果你对列进行了(+,-,*,/,!), 那么都将不会走索引。

SELECT * FROM user WHERE age - 1 = 20;

6、or引起索引失效

7、模糊查询导致索引失效

SELECT * FROM user WHERE name LIKE '%冰';

模糊搜索如果你前缀也进行模糊搜索,那么不会走索引。

9、IS NULL不走索引,IS NOT NULL走索引

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

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

相关文章

uView NoNetwork 无网络提示

该组件无需任何配置&#xff0c;引入即可&#xff0c;内部自动处理所有功能和事件&#xff0c;有如下特点&#xff1a; 如果没有网络&#xff0c;该组件会以fixed定位&#xff0c;并且以很大的z-index值覆盖原来的内容。一旦有网络了&#xff0c;会自动隐藏该组件&#xff0c;…

关 于 早 起

这篇文章我想谈谈关于早起这个问题。 其实我的作息并不是十分的规律&#xff0c;特别是在家&#xff0c;我基本上就是晚上睡得很晚&#xff0c;早上起的也晚&#xff0c;一天吃不了三顿饭那种。我现在还有印象&#xff0c;那时候我差点废了。身体也不好&#xff0c;睡眠质量也…

【ollama】(4):在autodl中安装ollama工具,配置环境变量,修改端口,使用RTX 3080 Ti显卡,测试coder代码生成大模型

1&#xff0c;ollama项目 Ollama 是一个强大的框架&#xff0c;设计用于在 Docker 容器中部署 LLM。Ollama 的主要功能是在 Docker 容器内部署和管理 LLM 的促进者&#xff0c;它使该过程变得非常简单。它帮助用户快速在本地运行大模型&#xff0c;通过简单的安装指令&#xf…

数据结构与算法第五套大题

1.图的最小生成树&#xff0c;各边权值之和&#xff1a; E{(1,5),(5,2),(5,3),(3,4)},W10 2.平均查找长度&#xff1a; 方法论&#xff1a; 直接将其变成一颗二叉树&#xff0c;然后计算每个节点的数学期望*比较次数之和/7 比如&#xff1a; 15为1/7&#xff0c;只需要比较一次…

Java后端八股文之Redis

文章目录 1. Redis是什么&#xff1f;2. Redis为什么这么快&#xff1f;3. 为什么要使用缓存&#xff1f;4. Redis几种使用场景&#xff1a;5. Redis的Zset底层为什么要使用跳表而不是平衡树、红黑树或者B树&#xff1f;6.Redis持久化6.1 什么是RDB持久化6.1.1RDB创建快照会阻塞…

OGNL表达式

文章目录 一、简介二、快速入门三、详细使用3.1 基本数据类型3.2 对象类型3.3 List集合3.4 Set集合3.5 Map集合3.6 数组3.7 静态调用3.8 算术运算3.9 逻辑运算3.10 同时执行多个表达式3.11 位运算 Ognl使用总结 - 源链接在此 >> 一、简介 OGNL&#xff08;Object-Graph…

华为OD机试2024年最新题库(Python、JAVA、C++合集)

我是一名软件开发培训机构老师&#xff0c;我的学生已经有上百人通过了华为OD机试&#xff0c;学生们每次考完试&#xff0c;会把题目拿出来一起交流分享。 重要&#xff1a;2023年11月份开始&#xff0c;考的都是OD统一考试&#xff08;C卷&#xff09;&#xff0c;题库已经整…

python3:No module named ‘pandas‘

一、背景 电脑里下载了python3&#xff0c;vscode使用的是python 书接上条博文&#xff0c;在我设置了vscode的默认地址后&#xff0c;下载pandas运行还是找不到 这里看到我已经成功的安装了pandas-2.2.1 二、发现问题 在设置vscode默认的python环境中寻找pandas&#xff08;…

入门了解使用huggingface实现ALBERT模型相关任务--文本分类相关任务

目录 引言 使用技巧 使用ALBERT进行文本分类 class transformers.AlbertForSequenceClassification 主要参数 主要方法 输入参数 返回值 使用示例 class transformers.TFAlbertForSequenceClassification 主要参数 特点和使用 输入格式支持 call方法参数 返回值…

Android Gradle 开发与应用 (六) : 创建buildSrc插件和使用命令行创建Gradle插件

1. 前言 前文中&#xff0c;我们介绍了在Android中&#xff0c;如何基于Gradle 8.2&#xff0c;创建Gradle插件。这篇文章&#xff0c;我们以buildSrc的方式来创建Gradle插件。此外&#xff0c;还介绍一种用Cmd命令行的方式&#xff0c;来创建独立的Gradle插件的方式。 1.1 本…

遍历与复制数组

&#xff08;1&#xff09;遍历数组 Arrays类调用public static String toString(int[]a)方法&#xff0c;可以得到参数指定的一维数组a的如下格式的字符串表示:a[0],a[1]~a[a.length-1] (2)复制数组 Arrays类调用public static double[]copyOf(double[]original,int newLen…

项目搭建常用镜像

Android项目 Gradle腾讯镜像&#xff1a; https://mirrors.cloud.tencent.com/gradle/****&#xff08;如&#xff1a;gradle-6.9.3-bin.zip&#xff09; 阿里云谷歌镜像&#xff1a; http://maven.aliyun.com/nexus/content/repositories/google 阿里云jcenter镜像 http://ma…

Sklearn交叉验证

scikit-learn提供了多种交叉验证的方法&#xff0c;主要包括以下几种类型&#xff1a; K折交叉验证&#xff08;K-Fold Cross Validation&#xff09;: 这种方法将数据集分成K个大小相等的互斥子集。每次选择一个子集作为验证集&#xff0c;剩余的K-1个子集作为训练集。这个过…

Django中的ajax细节

原代码 <script>$(function () {// 根据id获取展示框var viewer $3Dmol.createViewer("gldiv");var pdbModel, sdfModel;var colorpdb 700080, colorsdf 000F00;// 这里两个src表示文件路径var sdf ../resources/sdf/99.sdf;var pdb ../resources/pdb/4i…

idea:忽略不要搜索unpackage文件夹

开发vue时搜索关键字&#xff0c;会搜索到编译后的文件&#xff0c;如unpackage。&#xff08;注意这个是idea工具&#xff0c;和Git忽略是有区别的&#xff09; File->Settings->Editor->File Types

c 语言中指针注意事项

看看下面两个 #include<iostream> using namespace std;int main() {int a 10;char p[6];*((int *)p) *(& a); // 正确写法*p *(&a); // 错误写法cout << *(int*)p; } 把原因写在评论区

由于 Positive Technologies 的专业知识,Moxa 消除了工业无线转换器中的一个漏洞。

我们的专家在 NPort W2150A 和 W2250A 转换器中发现了该漏洞 - 这些设备可将工业控制器、仪表和传感器连接到本地 Wi-Fi 网络。Moxa 已根据负责任的披露政策通知了该威胁&#xff0c;并发布了软件更新。 &#x1f977; 攻击者可以完全访问这些设备。 Positive Technologies 公…

关于学习时间

这篇文章我来说一下我对于我最近学习时间的一些思考。 早上和下午是我最为活跃和高效的时间段。 我能够专注地工作&#xff0c;不容易分心。 然而&#xff0c;到了晚上&#xff0c;我的状态开始下降&#xff0c;这是很正常的情况。 由于早上和下午的专注学习&#xff0c;我的大…

【FAQ】推送获取push token报错6003,如何排查?

一、问题现象 客户端调用getToken方法获取push token失败并报错&#xff0c;关键错误日志&#xff1a;com.huawei.hms.common. ApiException: 6003: certificate fingerprint error。 二、问题排查 6003错误码在“常见错误码”说明文档中有说明&#xff1a; 检查申请相关服务…

JSONObject在Android Main方法中无法实例化问题

目录 前言一、Main(非安卓环境)方法下运行二、安卓坏境下运行三、why? 前言 原生的json,即org.json.JSONObject; 在Android Studio中的Main方法里运行报错&#xff0c;但在安卓程序运行过程正常 一、Main(非安卓环境)方法下运行 static void test() {try {// 创建一个 JSON …