![](https://img-blog.csdnimg.cn/20201127090750260.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224)
MySQL实战45讲
文章平均质量分 95
非原创,真干货的MySQL实战45讲,欢迎大家拜读!
aiguangyuan
要全身心的投入,程序才会有些感觉!
展开
-
MySQL实战第四十五讲- 自增id用完怎么办?
MySQL 里有很多自增的 id,每个自增 id 都是定义了初始值,然后不停地往上加步长。虽然自然数是没有上限的,但是在计算机里,只要定义了表示这个数的字节长度,那它就有上限。比如,无符号整型 (unsigned int) 是 4 个字节,上限就是 2^32-1。既然自增 id 有上限,就有可能被用完。但是,自增 id 用完了会怎么样呢?今天这篇文章,我们就来看看 MySQL 里面的几种自增 id,一起分析一下它们的值达到上限以后,会出现什么情况。表定义自增值 id说到自增 id,你第一转载 2021-09-19 15:35:13 · 887 阅读 · 0 评论 -
MySQL实战第四十四讲- 答疑文章:说一说这些好问题
这是我们专栏的最后一篇答疑文章,今天我们来说说一些好问题。在我看来,能够帮我们扩展一个逻辑的边界的问题,就是好问题。因为通过解决这样的问题,能够加深我们对这个逻辑的理解,或者帮我们关联到另外一个知识点,进而可以帮助我们建立起自己的知识网络。在工作中会问好问题,是一个很重要的能力。经过这段时间的学习,从评论区的问题我可以感觉出来,紧跟课程学习的同学,对 SQL 语句执行性能的感觉越来越好了,提出的问题也越来越细致和精准了。接下来,我们就一起看看同学们在评论区提到的这些好问题。在和你一起分析这些转载 2021-09-14 22:03:09 · 299 阅读 · 0 评论 -
MySQL实战第四十三讲- 要不要使用分区表?
我经常被问到这样一个问题:分区表有什么问题,为什么公司规范不让使用分区表呢?今天,我们就来聊聊分区表的使用行为,然后再一起回答这个问题。分区表是什么?为了说明分区表的组织形式,我先创建一个表 t:CREATE TABLE `t` ( `ftime` datetime NOT NULL, `c` int(11) DEFAULT NULL, KEY (`ftime`)) ENGINE=InnoDB DEFAULT CHARSET=latin1PARTITION BY RANGE (转载 2021-09-12 17:22:58 · 541 阅读 · 0 评论 -
MySQL实战第四十二讲- grant之后要跟着flush privileges吗?
在 MySQL 里面,grant 语句是用来给用户赋权的。不知道你有没有见过一些操作文档里面提到,grant 之后要马上跟着执行一个 flush privileges 命令,才能使赋权语句生效。我最开始使用 MySQL 的时候,就是照着一个操作文档的说明按照这个顺序操作的。那么,grant 之后真的需要执行 flush privileges 吗?如果没有执行这个 flush 命令的话,赋权语句真的不能生效吗?接下来,我就先和你介绍一下 grant 语句和 flush privileges 语句分别做转载 2021-09-12 12:53:22 · 277 阅读 · 0 评论 -
MySQL实战第四十一讲- 怎么最快地复制一张表?
我在上一篇文章最后,给你留下的问题是怎么在两张表中拷贝数据。如果可以控制对源表的扫描行数和加锁范围很小的话,我们简单地使用 insert … select 语句即可实现。当然,为了避免对源表加读锁,更稳妥的方案是先将数据写到外部文本文件,然后再写回目标表。这时,有两种常用的方法。接下来的内容,我会和你详细展开一下这两种方法。为了便于说明,我还是先创建一个表 db1.t,并插入 1000 行数据,同时创建一个相同结构的表 db2.t。create database db1;use db1;转载 2021-09-12 09:56:47 · 350 阅读 · 0 评论 -
MySQL实战第四十讲- insert语句的锁为什么这么多?
在上一篇文章中,我提到 MySQL 对自增主键锁做了优化,尽量在申请到自增 id 以后,就释放自增锁。因此,insert 语句是一个很轻量的操作。不过,这个结论对于“普通的 insert 语句”才有效。也就是说,还有些 insert 语句是属于“特殊情况”的,在执行过程中需要给其他资源加锁,或者无法在申请到自增 id 以后就立马释放自增锁。那么,今天这篇文章,我们就一起来聊聊这个话题。insert … select 语句我们先从昨天的问题说起吧。表 t 和 t2 的表结构、初始化数据语句转载 2021-08-21 09:26:32 · 468 阅读 · 0 评论 -
MySQL实战第三十九讲-自增主键为什么不是连续的?
在 第4篇 文章中,我们提到过自增主键,由于自增主键可以让主键索引尽量地保持递增顺序插入,避免了页分裂,因此索引更紧凑。之前我见过有的业务设计依赖于自增主键的连续性,也就是说,这个设计假设自增主键是连续的。但实际上,这样的假设是错的,因为自增主键不能保证连续递增。今天这篇文章,我们就来说说这个问题,看看什么情况下自增主键会出现 “空洞”?为了便于说明,我们创建一个表 t,其中 id 是自增主键字段、c 是唯一索引。CREATE TABLE `t` ( `id` int(11) NOT转载 2021-08-19 16:20:39 · 861 阅读 · 0 评论 -
MySQL实战第三十八讲- 都说InnoDB好,那还要不要使用Memory引擎?
我在上一篇文章末尾留给你的问题是:两个 group by 语句都用了 order by null,为什么使用内存临时表得到的语句结果里,0 这个值在最后一行;而使用磁盘临时表得到的结果里,0 这个值在第一行?今天我们就来看看,出现这个问题的原因吧。内存表的数据组织结构为了便于分析,我来把这个问题简化一下,假设有以下的两张表 t1 和 t2,其中表 t1 使用 Memory 引擎, 表 t2 使用 InnoDB 引擎。create table t1(id int primary key,转载 2021-08-18 11:41:27 · 254 阅读 · 0 评论 -
MySQL实战第三十七讲- 什么时候会使用内部临时表?
在 第16篇 和 第34篇 文章中,我分别和你介绍了 sort buffer、内存临时表和 join buffer。这三个数据结构都是用来存放语句执行过程中的中间数据,以辅助 SQL 语句的执行的。其中,我们在排序的时候用到了 sort buffer,在使用 join 语句的时候用到了 join buffer。然后,你可能会有这样的疑问,MySQL 什么时候会使用内部临时表呢?今天这篇文章,我就先给你举两个需要用到内部临时表的例子,来看看内部临时表是怎么工作的。然后,我们再来分析,什么情况下会使用内转载 2021-08-17 11:42:03 · 303 阅读 · 0 评论 -
MySQL实战第三十六讲- 为什么临时表可以重名?
在上一篇文章中,我们在优化 join 查询的时候使用到了临时表。当时,我们是这么用的:create temporary table temp_t like t1;alter table temp_t add index(b);insert into temp_t select * from t2 where b>=1 and b<=2000;select * from t1 join temp_t on (t1.b=temp_t.b);你可能会有疑问,为什么要用临时表呢?直接用普转载 2021-08-17 09:24:44 · 377 阅读 · 0 评论 -
MySQL实战第三十五讲- join语句怎么优化?
在上一篇文章中,我和你介绍了 join 语句的两种算法,分别是 Index Nested-Loop Join(NLJ) 和 Block Nested-Loop Join(BNL)。我们发现在使用 NLJ 算法的时候,其实效果还是不错的,比通过应用层拆分成多个语句然后再拼接查询结果更方便,而且性能也不会差。但是,BNL 算法在大表 join 的时候性能就差多了,比较次数等于两个表参与 join 的行数的乘积,很消耗 CPU 资源。当然了,这两个算法都还有继续优化的空间,我们今天就来聊聊这个话题。转载 2021-08-08 12:26:48 · 570 阅读 · 0 评论 -
MySQL实战第三十四讲- 到底可不可以使用join?
在实际生产中,关于 join 语句使用的问题,一般会集中在以下两类:1.我们 DBA 不让使用 join,使用 join 有什么问题呢?2.如果有两个大小不同的表做 join,应该用哪个表做驱动表呢?今天这篇文章,我就先跟你说说 join 语句到底是怎么执行的,然后再来回答这两个问题。为了便于量化分析,我还是创建两个表 t1 和 t2 来和你说明。CREATE TABLE `t2` ( `id` int(11) NOT NULL, `a` int(11) DEFAULT N..转载 2021-08-07 14:26:09 · 406 阅读 · 0 评论 -
MySQL实战第三十三讲- 我查这么多数据,会不会把数据库内存打爆?
我经常会被问到这样一个问题:我的主机内存只有 100G,现在要对一个 200G 的大表做全表扫描,会不会把数据库主机的内存用光了?这个问题确实值得担心,被系统 OOM(out of memory)可不是闹着玩的。但是,反过来想想,逻辑备份的时候,可不就是做整库扫描吗?如果这样就会把内存吃光,逻辑备份不是早就挂了?所以说,对大表做全表扫描,看来应该是没问题的。但是,这个流程到底是怎么样的呢?全表扫描对 server 层的影响假设,我们现在要对一个 200G 的 InnoDB 表 db1.转载 2021-08-07 09:50:01 · 383 阅读 · 0 评论 -
MySQL实战第三十二讲-为什么还有kill不掉的语句?
在 MySQL 中有两个 kill 命令:一个是 kill query + 线程 id,表示终止这个线程中正在执行的语句;一个是 kill connection + 线程 id,这里 connection 可缺省,表示断开这个线程的连接,当然如果这个线程有语句正在执行,也是要先停止正在执行的语句的。不知道你在使用 MySQL 的时候,有没有遇到过这样的现象:使用了 kill 命令,却没能断开这个连接。再执行 show processlist 命令,看到这条语句的 Command 列显示的是 Killed转载 2021-08-04 18:19:48 · 500 阅读 · 0 评论 -
MySQL实战第三十一讲- 误删数据后除了跑路,还能怎么办?
今天我要和你讨论的是一个沉重的话题:误删数据。在前面几篇文章中,我们介绍了 MySQL 的高可用架构。当然,传统的高可用架构是不能预防误删数据的,因为主库的一个 drop table 命令,会通过 binlog 传给所有从库和级联从库,进而导致整个集群的实例都会执行这个命令。虽然我们之前遇到的大多数的数据被删,都是运维同学或者 DBA 背锅的。但实际上,只要有数据操作权限的同学,都有可能踩到误删数据这条线。今天我们就来聊聊误删数据前后,我们可以做些什么,减少误删数据的风险,和由误删数据带来的损失转载 2021-08-01 20:32:18 · 441 阅读 · 0 评论 -
MySQL实战第三十讲-用动态的观点看加锁
在 第20篇和 第21篇 文章中,我和你介绍了 InnoDB 的间隙锁、next-key lock,以及加锁规则,在这两篇文章的评论区,出现了很多高质量的留言,我觉得通过分析这些问题,可以帮助你加深对加锁规则的理解。所以,我就从中挑选了几个有代表性的问题,构成了今天这篇答疑文章的主题,即用动态的观点看加锁。为了方便你理解,我们再一起复习一下加锁规则。这个规则中,包含了两个“原则”、两个“优化”和一个“bug”:原则 1:加锁的基本单位是 next-key lock。希望你还记得,next-ke.转载 2021-07-18 14:21:23 · 339 阅读 · 0 评论 -
MySQL实战第二十九讲-如何判断一个数据库是不是出问题了?
我在 第25 和 第27 篇文章中,和你介绍了主备切换流程。通过这些内容的讲解,你应该已经很清楚了:在一主一备的双 M 架构里,主备切换只需要把客户端流量切到备库;而在一主多从架构里,主备切换除了要把客户端流量切到备库外,还需要把从库接到新主库上。主备切换有两种场景,一种是主动切换,一种是被动切换。而其中被动切换,往往是因为主库出问题了,由 HA 系统发起的。这也就引出了我们今天要讨论的问题:怎么判断一个主库出问题了?你一定会说,这很简单啊,连上 MySQL,执行个 select 1 就好了。但转载 2021-07-18 10:00:14 · 379 阅读 · 0 评论 -
MySQL实战第二十八讲-读写分离有哪些坑?
在上一篇文章中,我和你介绍了一主多从的结构以及切换流程。今天我们就继续聊聊一主多从架构的应用场景:读写分离,以及怎么处理主备延迟导致的读写分离问题。我们在上一篇文章中提到的一主多从的结构,其实就是读写分离的基本结构了。这里,我再把这张图贴过来,方便你理解。如下 图 1 所示为读写分离基本结构。读写分离的主要目标就是分摊主库的压力。上图的结构是客户端(client)主动做负载均衡,这种模式下一般会把数据库的连接信息放在客户端的连接层。也就是说,由客户端来选择后端数据库进行查询。还有一种架构转载 2021-07-17 23:58:51 · 365 阅读 · 0 评论 -
MySQL实战第二十七讲-主库出问题了,从库怎么办?
在前面的第24、25和26篇文章中,介绍了 MySQL 主备复制的基础结构,但这些都是一主一备的结构。大多数的互联网应用场景都是读多写少,因此你负责的业务,在发展过程中很可能先会遇到读性能的问题。而在数据库层解决读性能问题,就要涉及到接下来两篇文章要讨论的架构:一主多从。今天这篇文章,我们就先聊聊一主多从的切换正确性。然后,我们在下一篇文章中再聊聊解决一主多从的查询逻辑正确性的方法。如图 1 所示,就是一个基本的一主多从结构。图中,虚线箭头表示的是主备关系,也就是 A 和 A’互为主备.转载 2021-05-14 16:59:56 · 504 阅读 · 0 评论 -
MySQL实战第二十六讲-备库为什么会延迟好几个小时?
在上一篇文章中,我和你介绍了几种可能导致备库延迟的原因。你会发现,这些场景里,不论是偶发性的查询压力,还是备份,对备库延迟的影响一般是分钟级的,而且在备库恢复正常以后都能够追上来。但是,如果备库执行日志的速度持续低于主库生成日志的速度,那这个延迟就有可能成了小时级别。而且对于一个压力持续比较高的主库来说,备库很可能永远都追不上主库的节奏。这就涉及到今天我要给你介绍的话题:备库并行复制能力。为了便于你理解,我们再一起看一下第 24 篇文章《MySQL 是怎么保证主备一致的?》的主备流程图。如下转载 2021-04-19 11:28:53 · 461 阅读 · 1 评论 -
MySQL实战第二十五讲-MySQL是怎么保证高可用的?
在上一篇文章中,介绍了 binlog 的基本内容,在一个主备关系中,每个备库接收主库的 binlog 并执行。正常情况下,只要主库执行更新生成的所有 binlog,都可以传到备库并被正确地执行,备库就能达到跟主库一致的状态,这就是最终一致性。但是,MySQL 要提供高可用能力,只有最终一致性是不够的。为什么这么说呢?今天我就着重和你分析一下。这里,我再放一次上一篇文章中讲到的双 M 结构的主备切换流程图。如下图1 所示为MySQL 主备切换流程 -- 双 M 结构图:主备延...转载 2021-04-17 14:45:15 · 336 阅读 · 0 评论 -
MySQL实战第二十四讲-MySQL是怎么保证主备一致的?
在前面的文章中,我不止一次地和你提到了 binlog,大家知道 binlog 可以用来归档,也可以用来做主备同步,但它的内容是什么样的呢?为什么备库执行了 binlog 就可以跟主库保持一致了呢?今天我就正式地和你介绍一下它。毫不夸张地说,MySQL 能够成为现下最流行的开源数据库,binlog 功不可没。在最开始,MySQL 是以容易学习和方便的高可用架构,被开发人员青睐的。而它的几乎所有的高可用架构,都直接依赖于 binlog。虽然这些高可用架构已经呈现出越来越复杂的趋势,但都是从最基本的一主一转载 2020-12-16 00:49:24 · 566 阅读 · 2 评论 -
MySQL实战第二十三讲-MySQL是怎么保证数据不丢的?
今天这篇文章,我会继续和你介绍在业务高峰期临时提升性能的方法。从文章标题“MySQL 是怎么保证数据不丢的?”,你就可以看出来,今天我和你介绍的方法,跟数据的可靠性有关。在专栏前面文章和答疑篇中,我都着重介绍了 WAL 机制(你可以再回顾下第 2 篇、第 9 篇、第 12 篇和第 15 篇文章中的相关内容),得到的结论是:只要 redo log 和 binlog 保证持久化到磁盘,就能确保 MySQL 异常重启后,数据可以恢复。评论区有同学又继续追问,redo log 的写入流程是怎么样的,如何保证转载 2020-11-29 09:39:35 · 655 阅读 · 0 评论 -
MySQL实战第二十二讲-MySQL有哪些“饮鸩止渴”提高性能的方法?
不知道你在实际运维过程中有没有碰到这样的情景:业务高峰期,生产环境的 MySQL 压力太大,没法正常响应,需要短期内、临时性地提升一些性能。我以前做业务护航的时候,就偶尔会碰上这种场景。用户的开发负责人说,不管你用什么方案,让业务先跑起来再说。但,如果是无损方案的话,肯定不需要等到这个时候才上场。今天我们就来聊聊这些临时方案,并着重说一说它们可能存在的风险。短连接风暴正常的短连接模式就是连接到数据库后,执行很少的 SQL 语句就断开,下次需要的时候再重连。如果使用的是短连接,在业务高峰.转载 2020-11-28 00:08:39 · 487 阅读 · 0 评论 -
MySQL实战第二十一讲-为什么我只改一行的语句,锁这么多?
在上一篇文章中,我和你介绍了间隙锁和 next-key lock 的概念,但是并没有说明加锁规则。间隙锁的概念理解起来确实有点儿难,尤其在配合上行锁以后,很容易在判断是否会出现锁等待的问题上犯错。所以今天,我们就先从这个加锁规则开始吧。首先说明一下,这些加锁规则我没在别的地方看到过有类似的总结,以前我自己判断的时候都是想着代码里面的实现来脑补的。这次为了总结成不看代码的同学也能理解的规则,是我又重新刷了代码临时总结出来的。所以,这个规则有以下两条前提说明:1.MySQL 后面的版本可能会改变加.转载 2020-11-23 23:57:44 · 480 阅读 · 0 评论 -
MySQL实战第二十讲-幻读是什么,幻读有什么问题?
在上一篇文章最后,我给你留了一个关于加锁规则的问题,今天,我们就从这个问题说起吧。为了便于说明问题,这一篇文章,我们就先使用一个小一点儿的表,建表和初始化语句如下:CREATE TABLE `t` ( `id` int(11) NOT NULL, `c` int(11) DEFAULT NULL, `d` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `c` (`c`)) ENGINE=InnoDB;insert into t转载 2020-11-22 20:43:55 · 602 阅读 · 0 评论 -
MySQL实战第十九讲-为什么我只查一行的语句,也执行这么慢?
一般情况下,如果我跟你说查询性能优化,你首先会想到一些复杂的语句,想到查询需要返回大量的数据。但有些情况下,“查一行”,也会执行得特别慢。今天,我就跟你聊聊这个有趣的话题,看看什么情况下,会出现这个现象。需要说明的是,如果 MySQL 数据库本身就有很大的压力,导致数据库服务器 CPU 占用率很高或 ioutil(IO 利用率)很高,这种情况下所有语句的执行都有可能变慢,不属于我们今天的讨论范围。为了便于描述,我还是构造一个表,基于这个表来说明今天的问题。这个表有两个字段 id 和 c,并且我在里面转载 2020-11-22 01:21:19 · 522 阅读 · 0 评论 -
MySQL实战十八讲-为什么这些SQL语句逻辑相同,性能却差异巨大?
在 MySQL 中,有很多看上去逻辑相同,但性能却差异巨大的 SQL 语句。对这些语句使用不当的话,就会不经意间导致整个数据库的压力变大。我今天挑选了三个这样的案例和你分享。希望再遇到相似的问题时,你可以做到举一反三、快速解决问题。案例一:条件字段函数操作假设你现在维护了一个交易系统,其中交易记录表 tradelog 包含交易流水号(tradeid)、交易员 id(operator)、交易时间(t_modified)等字段。为了便于描述,我们先忽略其他字段。这个表的建表语句如下:CR.转载 2020-11-21 14:39:24 · 609 阅读 · 0 评论 -
MySQL实战第十七讲-如何正确地显示随机消息?
我在上一篇文章,为你讲解完 order by 语句的几种执行模式后,就想到了之前一个做英语学习 App 的朋友碰到过的一个性能问题。今天这篇文章,我就从这个性能问题说起,和你说说 MySQL 中的另外一种排序需求,希望能够加深你对 MySQL 排序逻辑的理解。这个英语学习 App 首页有一个随机显示单词的功能,也就是根据每个用户的级别有一个单词表,然后这个用户每次访问首页的时候,都会随机滚动显示三个单词。他们发现随着单词表变大,选单词这个逻辑变得越来越慢,甚至影响到了首页的打开速度。现在,如果让你来转载 2020-11-20 14:08:27 · 597 阅读 · 0 评论 -
MySQL实战第十六讲-“order by”是怎么工作的?
在你开发应用的时候,一定会经常碰到需要根据指定的字段排序来显示结果的需求。还是以我们前面举例用过的市民表为例,假设你要查询城市是“杭州”的所有人名字,并且按照姓名排序返回前 1000 个人的姓名、年龄。假设这个表的部分定义是这样的:CREATE TABLE `t` ( `id` int(11) NOT NULL, `city` varchar(16) NOT NULL, `name` varchar(16) NOT NULL, `age` int(11) NOT NULL, `转载 2020-11-19 21:03:15 · 517 阅读 · 0 评论 -
MySQL实战第十五讲-日志和索引相关问题
日志相关问题我在第 2 篇文章《MySQL深入学习第二篇 - 一条SQL更新语句是如何执行的?》中,和你讲到 binlog(归档日志)和 redo log(重做日志)配合崩溃恢复的时候,用的是反证法,说明了如果没有两阶段提交,会导致 MySQL 出现主备数据不一致等问题。在这篇文章下面,很多同学在问,在两阶段提交的不同瞬间,MySQL 如果发生异常重启,是怎么保证数据完整性的?现在,我们就从这个问题开始吧。我再放一次两阶段提交的图,方便你学习下面的内容。如下 图1 所示阶段提交示意图:转载 2020-11-17 22:40:23 · 2230 阅读 · 7 评论 -
MySQL实战第十四讲-count(*)这么慢,我该怎么办?
在开发系统的时候,你可能经常需要计算一个表的行数,比如一个交易系统的所有变更记录总数。这时候你可能会想,一条 select count(*) from t 语句不就解决了吗?但是,你会发现随着系统中记录数越来越多,这条语句执行得也会越来越慢。然后你可能就想了,MySQL 怎么这么笨啊,记个总数,每次要查的时候直接读出来,不就好了吗。那么今天,我们就来聊聊 count(*) 语句到底是怎样实现的,以及 MySQL 为什么会这么实现。然后,我会再和你说说,如果应用中有这种频繁变更并需要统计表行数的需求,转载 2020-11-16 00:06:15 · 764 阅读 · 0 评论 -
MySQL实战第十三讲-为什么表数据删掉一半,表文件大小不变?
经常会有同学来问我,我的数据库占用空间太大,我把一个最大的表删掉了一半的数据,怎么表文件的大小还是没变?那么今天,我就和你聊聊数据库表的空间回收,看看如何解决这个问题。这里,我们还是针对 MySQL 中应用最广泛的 InnoDB 引擎展开讨论。一个 InnoDB 表包含两部分,即:表结构定义和数据。在 MySQL 8.0 版本以前,表结构是存在以.frm 为后缀的文件里。而 MySQL 8.0 版本,则已经允许把表结构定义放在系统数据表中了。因为表结构定义占用的空间很小,所以我们今天主要讨论的是表数转载 2020-11-15 19:47:01 · 490 阅读 · 0 评论 -
MySQL实战第十二讲-为什么我的MySQL会“抖”一下?
平时的工作中,不知道你有没有遇到过这样的场景,一条 SQL 语句,正常执行的时候特别快,但是有时也不知道怎么回事,它就会变得特别慢,并且这样的场景很难复现,它不只随机,而且持续时间还很短。看上去,这就像是数据库“抖”了一下。今天,我们就一起来看一看这是什么原因。你的 SQL 语句为什么变“慢”了在本栏第 2 篇文章《MySQL深入学习第二篇 - 一条SQL更新语句是如何执行的?》中,我为你介绍了 WAL 机制。现在你知道了,InnoDB 在处理更新语句的时候,只做了写日志这一个磁盘操作。这.转载 2020-11-15 14:02:11 · 479 阅读 · 0 评论 -
MySQL实战第十一讲-怎么给字符串字段加索引?
现在,几乎所有的系统都支持邮箱登录,如何在邮箱这样的字段上建立合理的索引,是我们今天要讨论的问题。假设,你现在维护一个支持邮箱登录的系统,用户表是这么定义的:create table SUser( ID bigint unsigned primary key, email varchar(64), ... )engine=innodb; 由于要使用邮箱登录,所以业务代码中一定会出现类似于这样的语句:select f1, f2 from SUser where email=转载 2020-11-15 11:53:45 · 810 阅读 · 0 评论 -
MySQL实战第十讲-MySQL为什么有时候会选错索引?
前面我们介绍过索引,你已经知道了在 MySQL 中一张表其实是可以支持多个索引的。但是,你写 SQL 语句的时候,并没有主动指定使用哪个索引。也就是说,使用哪个索引是由 MySQL 来确定的。不知道你有没有碰到过这种情况,一条本来可以执行得很快的语句,却由于 MySQL 选错了索引,而导致执行速度变得很慢?我们一起来看一个例子吧。我们先建一个简单的表,表里有 a、b 两个字段,并分别建上索引:CREATE TABLE `t` ( `id` int(11) NOT NULL, `a`转载 2020-11-13 22:54:04 · 554 阅读 · 0 评论 -
MySQL实战第九讲-普通索引和唯一索引,应该怎么选择?
在前面的基础篇文章中,我给你介绍过索引的基本概念,相信你已经了解了唯一索引和普通索引的区别。今天我们就继续来谈谈,在不同的业务场景下,应该选择普通索引,还是唯一索引?假设你在维护一个市民系统,每个人都有一个唯一的身份证号,而且业务代码已经保证了不会写入两个重复的身份证号。如果市民系统需要按照身份证号查姓名,就会执行类似这样的 SQL 语句:select name from CUser where id_card = 'xxxxxxxyyyyyyzzzzz';所以,你一定会考虑在 id_card转载 2020-11-12 00:06:41 · 536 阅读 · 0 评论 -
MySQL实战第八讲 - 事务到底是隔离的还是不隔离的?
我在第 3 篇文章和你讲事务隔离级别的时候提到过,如果是可重复读隔离级别,事务 T 启动的时候会创建一个视图 read-view,之后事务 T 执行期间,即使有其他事务修改了数据,事务 T 看到的仍然跟在启动时看到的一样。也就是说,一个在可重复读隔离级别下执行的事务,好像与世无争,不受外界影响。但是,我在上一篇文章中,和你分享行锁的时候又提到,一个事务要更新一行,如果刚好有另外一个事务拥有这一行的行锁,它又不能这么超然了,会被锁住,进入等待状态。问题是,既然进入了等待状态,那么等到这个事务自己获取到行锁转载 2020-11-06 15:31:42 · 696 阅读 · 0 评论 -
MySQL实战第七讲 - 行锁功过:怎么减少行锁对性能的影响?
MySQL 的行锁是在引擎层由各个引擎自己实现的。但并不是所有的引擎都支持行锁,比如 MyISAM 引擎就不支持行锁。不支持行锁意味着并发控制只能使用表锁,对于这种引擎的表,同一张表上任何时刻只能有一个更新在执行,这就会影响到业务并发度。InnoDB 是支持行锁的,这也是 MyISAM 被 InnoDB 替代的重要原因之一。我们今天就主要来聊聊 InnoDB 的行锁,以及如何通过减少锁冲突来提升业务并发度。顾名思义,行锁就是针对数据表中行记录的锁。这很好理解,比如事务 A 更新了一行,而这时候事务转载 2020-10-29 23:28:07 · 694 阅读 · 0 评论 -
MySQL实战第六讲 - 全局锁和表锁 :给表加个字段怎么有这么多阻碍?
数据库锁设计的初衷是处理并发问题。作为多用户共享的资源,当出现并发访问的时候,数据库需要合理地控制资源的访问规则。而锁就是用来实现这些访问规则的重要数据结构。根据加锁的范围,MySQL 里面的锁大致可以分成全局锁、表级锁和行锁三类。今天这篇文章,将会分享全局锁和表级锁。而关于行锁的内容,会在下一篇文章中详细介绍。这里需要说明的是,锁的设计比较复杂,这两篇文章不会涉及锁的具体实现细节,主要介绍的是碰到锁时的现象和其背后的原理。全局锁顾名思义,全局锁就是对整个数据库实例加锁。MySQL 提供了一转载 2020-05-16 09:48:03 · 978 阅读 · 0 评论