![](https://img-blog.csdnimg.cn/20201014180756918.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
MySQL
文章平均质量分 92
mysql学习笔记
百炼之志
CSDN上都是我走过的路,希望对某个小伙伴有所帮助,就知足了。
我的终极目标是,在这里形成一个有深度的,系统的教程,我或者其他人,能再次学到东西,足矣。
展开
-
Mysql系列文章目录
这里的文章大部分来自 小林coding 的拷贝,他的文章非常有深度,不过由于他的文章是在自己搭建的网站上的,因此我这里粘贴再搞一份,避免后续网站找不到了。后续我自己也可能有一些补充。转载 2023-12-18 19:19:17 · 41 阅读 · 0 评论 -
揭开 Buffer Pool 的面纱
Innodb 存储引擎设计了一个缓冲池(Buffer Pool),来提高数据库的读写性能。Buffer Pool 以页为单位缓冲数据,可以通过 innodb_buffer_pool_size 参数调整缓冲池的大小,默认是 128 M。Free List (空闲页链表),管理空闲页;Flush List (脏页链表),管理脏页;LRU List,管理脏页+干净页,将最近且经常查询的数据缓存在其中,而不常查询的数据就淘汰出去。;转载 2023-12-27 13:41:09 · 25 阅读 · 0 评论 -
MySQL 日志:undo log、redo log、binlog 有什么用?
具体更新一条记录执行器负责具体执行,会调用存储引擎的接口,通过主键索引树搜索获取 id = 1 这一行记录:如果 id=1 这一行所在的数据页本来就在 buffer pool 中,就直接返回给执行器更新;如果记录不在 buffer pool,将数据页从磁盘读入到 buffer pool,返回记录给执行器。执行器得到聚簇索引记录后,会看一下更新前的记录和更新后的记录是否一样:如果一样的话就不进行后续更新流程;转载 2023-12-26 12:53:15 · 37 阅读 · 0 评论 -
字节面试:加了什么锁,导致死锁的?
两个事务即使生成的间隙锁的范围是一样的,也不会发生冲突,因为间隙锁目的是为了防止其他事务插入数据,因此间隙锁与间隙锁之间是相互兼容的。在执行插入语句时,如果插入的记录在其他事务持有间隙锁范围内,插入语句就会被阻塞,因为插入语句在碰到间隙锁时,会生成一个插入意向锁,然后插入意向锁和间隙锁之间是互斥的关系。转载 2023-12-26 11:13:16 · 22 阅读 · 0 评论 -
MySQL 死锁了,怎么办?
大家好,我是小林。说个很早之前自己遇到过数据库死锁问题。有个业务主要逻辑就是新增订单、修改订单、查询订单等操作。然后因为订单是不能重复的,所以当时在新增订单的时候做了幂等性校验,做法就是在新增订单记录之前,先通过 select … for update 语句查询订单是否存在,如果不存在才插入订单记录。而正是因为这样的操作,当业务量很大的时候,就可能会出现死锁。接下来跟大家聊下为什么会发生死锁,以及怎么避免死锁。转载 2023-12-25 23:05:08 · 144 阅读 · 0 评论 -
MySQL 记录锁+间隙锁可以防止删除操作而导致的幻读吗?
首先来看看 MySQL 文档是怎么定义幻读(Phantom Read)的:翻译:当同一个查询在不同的时间产生不同的结果集时,事务中就会出现所谓的幻象问题。例如,如果 SELECT 执行了两次,但第二次返回了第一次没有返回的行,则该行是“幻像”行。T1 时间执行的结果是有 5 条行记录,而 T2 时间执行的结果是有 6 条行记录,那就发生了幻读的问题。T1 时间执行的结果是有 5 条行记录,而 T2 时间执行的结果是有 4 条行记录,也是发生了幻读的问题。MySQL 是怎么解决幻读的?转载 2023-12-25 21:28:21 · 61 阅读 · 0 评论 -
update 没加索引会锁全表?
不要小看一条 update 语句,在生产机上使用不当可能会导致业务停滞,甚至崩溃。当我们要执行 update 语句的时候,确保 where 条件中带上了索引列,并且在测试机确认该语句是否走的是索引扫描,防止因为扫描全表,而对表中的所有记录加上锁。我们可以打开 MySQL sql_safe_updates 参数,这样可以预防 update 操作时 where 条件没有带上索引列。转载 2023-12-25 18:48:32 · 255 阅读 · 0 评论 -
MySQL 是怎么加锁的?
大家好,我是小林。是不是很多人都对 MySQL 加行级锁的规则搞的迷迷糊糊,对记录一会加的是 next-key 锁,一会加是间隙锁,一会又是记录锁。坦白说,确实还挺复杂的,但是好在我找点了点规律,也知道如何如何用命令分析加了什么类型的行级锁。之前我写过一篇关于「MySQL 是怎么加行级锁的?」的文章,随着我写 MySQL 锁相关的文章越来越多时,后来发现当时的文章写的不够详细。转载 2023-12-24 16:32:07 · 58 阅读 · 0 评论 -
MySQL 有哪些锁?
大家好,我是小林。这次,来说说 MySQL 的锁,主要是 Q&A 的形式,看起来会比较轻松。不多 BB 了,发车!在 MySQL 里,根据加锁的范围,可以分为全局锁、表级锁和行锁三类。转载 2023-12-24 12:22:28 · 28 阅读 · 0 评论 -
MySQL 可重复读隔离级别,完全解决幻读了吗?
首先来看看 MySQL 文档是怎么定义幻读(Phantom Read)的:翻译:当同一个查询在不同的时间产生不同的结果集时,事务中就会出现所谓的幻象问题。例如,如果 SELECT 执行了两次,但第二次返回了第一次没有返回的行,则该行是“幻像”行。T1 时间执行的结果是有 5 条行记录,而 T2 时间执行的结果是有 6 条行记录,那就发生了幻读的问题。T1 时间执行的结果是有 5 条行记录,而 T2 时间执行的结果是有 4 条行记录,也是发生了幻读的问题。转载 2023-12-24 10:35:44 · 108 阅读 · 0 评论 -
事务隔离级别是怎么实现的?
事务是在 MySQL 引擎层实现的,我们常见的 InnoDB 引擎是支持事务的,事务的四大特性是原子性、一致性、隔离性、持久性,我们这次主要讲的是隔离性。当多个事务并发执行的时候,会引发脏读、不可重复读、幻读这些问题,那为了避免这些问题,SQL 提出了四种隔离级别,分别是读未提交、读已提交、可重复读、串行化,从左往右隔离级别顺序递增,隔离级别越高,意味着性能越差,InnoDB 引擎的默认隔离级别是可重复读。转载 2023-12-23 23:59:53 · 24 阅读 · 0 评论 -
count(*) 和 count(1) 有什么区别?哪个性能最好?count(*) 和 count(1) 有什么区别?哪个性能最好?
大家好,我是小林。当我们对一张数据表中的记录进行统计的时候,习惯都会使用 count 函数来统计,但是 count 函数传入的参数有很多种,比如 count(1)、count(*)、count(字段) 等。到底哪种效率是最好的呢?是不是 count(*) 效率最差?我曾经以为 count(*) 是效率最差的,因为认知上 selete * from t 会读取所有表中的字段,所以凡事带有 * 字符的就觉得会读取表中所有的字段,当时网上有很多博客也这么说。转载 2023-12-23 23:08:42 · 122 阅读 · 0 评论 -
MySQL 使用 like “%x“,索引一定会失效吗?
要查询的数据就不能只在二级索引树里找了,得需要回表操作才能完成查询的工作,再加上是左模糊匹配,无法利用索引树的有序性来快速定位数据,所以得在二级索引树逐一遍历,获取主键值后,再到聚簇索引树检索到对应的数据行,这样实在太累了。首先,这张表的字段没有「非索引」字段,所以 select * 相当于 select id,name,然后这个查询的数据都在二级索引的 B+ 树,因为二级索引的 B+ 树的叶子节点包含「索引值+主键值」,所以查二级索引的 B+ 树就能查到全部结果了,这个就是覆盖索引。转载 2023-12-22 12:40:48 · 57 阅读 · 0 评论 -
索引失效有哪些?
当我们使用左或者左右模糊匹配的时候,也就是like %xx或者like %xx%这两种方式都会造成索引失效;当我们在查询条件中对索引列使用函数,就会导致索引失效。当我们在查询条件中对索引列进行表达式计算,也是无法走索引的。MySQL 在遇到字符串和数字比较的时候,会自动把字符串转为数字,然后再进行比较。如果字符串是索引列,而条件语句中的输入参数是数字的话,那么索引列会发生隐式类型转换,由于隐式类型转换是通过 CAST 函数实现的,等同于对索引列使用了函数,所以就会导致索引失效。转载 2023-12-22 11:45:07 · 16 阅读 · 0 评论 -
MySQL 单表不要超过 2000W 行,靠谱吗?
MySQL 的表数据是以页的形式存放的,页在磁盘中不一定是连续的。页的空间是 16K, 并不是所有的空间都是用来存放数据的,会有一些固定的信息,如,页头,页尾,页码,校验码等等。在 B+ 树中,叶子节点和非叶子节点的数据结构是一样的,区别在于,叶子节点存放的是实际的行数据,而非叶子节点存放的是主键和页号。索引结构不会影响单表最大行数,2000W 也只是推荐值,超过了这个值可能会导致 B + 树层级更高,影响查询性能。转载 2023-12-22 10:46:34 · 46 阅读 · 0 评论 -
为什么 MySQL 采用 B+ 树作为索引?
索引数据最好能按顺序排列,这样可以使用「二分查找法」高效定位数据。假设我们现在用数组来存储索引,比如下面有一个排序的数组,如果要从中找出数字 3,最简单办法就是从头依次遍历查询,这种方法的时间复杂度是 O(n),查询效率并不高。因为该数组是有序的,所以我们可以采用二分查找法,比如下面这张采用二分法的查询过程图:可以看到,二分查找法每次都把查询的范围减半,这样时间复杂度就降到了 O(logn),但是每次查找都需要不断计算中间位置。用数组来实现线性排序的数据虽然简单好用,但是插入新元素的时候性能太低。转载 2023-12-20 11:28:51 · 51 阅读 · 1 评论 -
从数据页的角度看 B+ 树
InnoDB 的数据是按「数据页」为单位来读写的,默认数据页大小为 16 KB。每个数据页之间通过双向链表的形式组织起来,物理上不连续,但是逻辑上连续。数据页内包含用户记录,每个记录之间用单向链表的方式组织起来,为了加快在数据页内高效查询记录,设计了一个页目录,页目录存储各个槽(分组),且主键值是有序的,于是可以通过二分查找法的方式进行检索从而提高效率。为了高效查询记录所在的数据页,InnoDB 采用 b+ 树作为索引,每个节点都是一个数据页。转载 2023-12-20 10:58:31 · 31 阅读 · 1 评论 -
索引常见面试题
当你想查阅书中某个知识的内容,你会选择一页一页的找呢?还是在书的目录去找呢?傻瓜都知道时间是宝贵的,当然是选择在书的目录去找,找到后再翻到对应的页。书中的目录,就是充当索引的角色,方便我们快速查找书中的内容,所以索引是以空间换时间的设计思想。那换到数据库中,索引的定义就是帮助存储引擎快速获取数据的一种数据结构,形象的说就是索引是数据的目录。所谓的存储引擎,说白了就是如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法。转载 2023-12-19 12:06:13 · 26 阅读 · 0 评论 -
MySQL 一行记录是怎么存储的?
MySQL 的 NULL 值是怎么存放的?MySQL 的 Compact 行格式中会用「NULL值列表」来标记值为 NULL 的列,NULL 值并不会存储在行格式中的真实数据部分。NULL值列表会占用 1 字节空间,当表中所有字段都定义成 NOT NULL,行格式中就不会有 NULL值列表,这样可节省 1 字节的空间。MySQL 怎么知道 varchar(n) 实际占用数据的大小?MySQL 的 Compact 行格式中会用「变长字段长度列表」存储变长字段实际占用的数据大小。转载 2023-12-19 10:07:02 · 50 阅读 · 0 评论 -
执行一条 select 语句,期间发生了什么?
执行一条 SQL 查询语句,期间发生了什么?连接器:建立连接,管理连接、校验用户身份;查询缓存:查询语句如果命中查询缓存则直接返回,否则继续往下执行。MySQL 8.0 已删除该模块;解析 SQL,通过解析器对 SQL 查询语句进行词法分析、语法分析,然后构建语法树,方便后续模块读取表名、字段、语句类型;执行 SQL:执行 SQL 共有三个阶段:预处理阶段:检查表或字段是否存在;将select *中的符号扩展为表上的所有列。优化阶段:基于查询成本的考虑, 选择查询成本最小的执行计划;转载 2023-12-18 20:25:24 · 34 阅读 · 0 评论