MySQL 面试问答

导航

  • 一、什么是回表查询?如何避免回表查询?
  • 二、为什么MySQL建议使用自增主键?什么是代理主键、业务主键?
  • 三、为什么MySQL建议单表不超过2000W数据?
  • 四、MySQL自增id用完了怎么办?
  • 五、MySQL自增主键是连续的吗?
  • 六、一条SQL语句在MySQL中是如何执行的?
  • 七、MySQL的存储引擎区别?

一、什么是回表查询?如何避免回表查询?

索引有两种类型,一种是基于表的主键建立的主键索引,另一种是基于普通列建立的普通索引(或二级索引)。主键索引和普通索引的查询过程和查询性能是不一样的。

普通索引的叶子节点除了索引数据本身外,仅只存储主键 id 值,而主键索引的叶子节点存储的是整条数据。当使用普通索引查询某个列时,这个列未保存在这个普通索引树中时,就需要再通过主键索引树定位到相应的记录,取得对应的数据,这就是回表。因此,使用普通索引查询数据可能会存在回表的情况,在能得知 id 的前提下,尽量直接使用主键索引查询数据。

使用覆盖索引可以避免回表查询,提高查询性能。
所谓覆盖索引,指的就是普通索引中存储的列足以返回查询想要的数据。为了达到这个目的,可以适当增加普通索引中存储的列,也就是使用组合索引,将多个列值联合组成一个索引。例如,(a, b, c) 三个列的组合索引,如果select的数据已经在这三列中,那么就不需要回表查询了。

二、为什么MySQL建议使用自增主键?什么是代理主键、业务主键?

代理主键,就是无意义的自增 id。自然主键,即业务主键,就是业务相关的编号,例如身份证、订单号这类。
1、业务主键更浪费空间。
2、业务主键无序,写入时需更长时间组织索引。为了使主键有序,需要进行索引重排,无序的编号需要频繁进行索引重排,降低入库性能(数据移动),而代理主键本身自增,不需要进行索引重排。
3、业务主键如果是字符串,在分库分表时,无法直接取模运算,需要先转换数字,处理更耗时。
4、业务主键在分布式系统中存在高耦合问题,一旦数据本身发生变化,系统极难维护。例如,用户系统、积分系统、账户系统(管理余额),如果用户系统以身份证作为主键,在系统间操作的时候需要传入这个主键,但如果是一个老人,身份证15位,而现在国家要求身份证必须更改为18位,其他系统都需要进行相应的更新,极大的增加了数据维护成本,系统之间耦合度太高。
5、业务主键可能存在冲突。例如如果是以身份证为id,那么在一个员工表中,假设一个员工离职,后因为某种原因又入职,一般的业务处理都是重新创建一条员工记录,但身份证号相同,就会存在主键冲突的问题。
6、如果没有指定自增id 主键,那么该表的第一个唯一非空索引被作为聚集索引。如果这个列是 char 类型的数据,会增加表的插入开销。
7、如果没有指定自增 id,也没有唯一非空索引,那么mysql就会自动生成一个隐藏的主键作为聚集索引,这个隐藏的主键是一个6个字节的列,这个列值也是自增的。

三、为什么MySQL建议单表不超过2000W数据?

InnoDB的B+树可以存放多少数据?答案是:约2千万。
这个数字如何计算?
计算机存储数据的最小单元是扇区,一个扇区的大小是512字节;文件系统的最小存储单元是4K;InnoDB的最小存储单元是页(Page),大小是16K。
因此,InnoDB的数据文件 .ibd 文件的大小始终是 16K的整数倍
表中的数据都存储在页中,假设一条数据大小为1K,那么一页就可以存储16条数据,它既可以存放数据,也可以存放键值+指针。在B+树中,叶子节点用页来存放数据,非叶子节点来存放键值+指针。
索引组织表通过非叶子节点的二分查找,以及指针确定数据在哪个页中,进而再去数据页查找需要的数据。
假设 B+ 树高为 2,即存在一个根节点和若干个叶子节点,那么这颗 B+树的存放总记录数为:

根节点指针数 × 单个叶子节点记录行数

假设一行数据 1K,一页存16行(这里假设一行记录的数据大小是1K,实际上现在很多互联网业务数据大小通常就是 1K左右)。
假设主键使用bigint类型,长度为 8 字节,而指针大小在InnoDB 源码中为 6 字节,所以,存储键值+指针的非叶子节点(页)能存储:16K÷(8 + 6) = 16384 / 14 = 1170。

高度为 2 的B+树,根节点可以存储1170个索引+指针,每个叶子节点可以存放 16 行数据,那么这个 B+ 树最多可以容纳的数据行数为:

1170 × 16 = 18720

以此算法计算高度为 3 的 B+ 树,无非多了一层非叶子节点,容易得到下面的计算公式:

1170 × 1170 × 16 = 21902400 ≈ 2 千万

所以在 InnoDB 中 B+ 树高度一般为 2 ~ 3层,就能够满足千万级的数据存储。在查找数据时,一次页的查找代表一次IO,通过主键索引查询通常只需要 1 ~ 3次IO 操作即可查找到数据。

四、MySQL自增id用完了怎么办?

我们一般在设计表的时候,会给表设置一个自增id。这个自增id是表级别的,每当我们要插入数据的时候会取得表的最大id并加一就是新数据的id。id的类型一般是 int,也有例如 tinyint。以无符号的tinyint 为例,它的最大值是2^8 - 1=255,那么当表中已经有255条记录之后,再新增数据就会报主键冲突

而另一种情况,如果没有为数据表设置主键,mysql会自动给表设置一个默认自增 row_id,这个row_id 最大可以达到 2^48 - 1。同样,当我们把最大的 row_id 用完,并不会报主键冲突,而是会从最小值开始从头开始,进而覆盖掉老数据,这个是个比较严重的问题,除非表中数据是类似日志这种允许擦除老数据。

五、MySQL自增主键是连续的吗?

MySQL自增主键不是连续的。就算步长为1,但也一定会出现空档的情况。
表的结构定义存放在后缀名为 .frm 的一个文件中,但它不会保存这个主键的自增值。不同的存储引擎对于自增主键的保存策略也有所不同。
自增 id 是如何存储的?
InnoDB 在MySQL 5.7 以前,主键的自增值(即最大的那个主键值)是保存在内存中的,并未持久化。每次重启mysql之后,第一次打开这个表,mysql都会去扫描这个表,找到最大id,然后加上步长(默认就是1)作为这个自增值保留在内存中。8.0 之后,增加了自增值持久化的能力,如果mysql突然宕机,重启后也可以从磁盘直接取得自增值,而不需要扫描,实际上是存储在 redo log 文件中。
MyISAM 是将自增值存储在数据文件中的。

自增策略是怎样的?
自增主键的自增策略是,默认情况下可以自增加一,但这种情况仅是当前我们未指定 id 字段的情况,如果有显式指定,例如,当前自增值为 x,此时插入一条数据,指定 id = y ( y > x),那么自增值就会更新成 y;如果 y < x,首先会判断是否冲突,若不冲突,自增值不会改变,依然是 x。

出现自增值不连续的情况:
1、唯一键冲突(注意不是主键冲突),插入失败,浪费自增资源。例如两个事务,A事务申请 id + 1,B事务申请 id + 2,但是A事务中包含的唯一键与表中某个唯一键冲突,导致插入失败,浪费了 id + 1这个资源,就会产生不连续的情况。
2、事务回滚。事务回滚不会恢复申请的自增资源。
3、对于批量插入的数据,id 自增会是上次的两倍。

为什么这些场景下不会恢复自增 id ?
如果要恢复为使用的自增id,例如插入失败,自增id不变,那么就必须增加相应的同步机制。例如并发场景下,例如给自增值加锁,并发请求时,必须等待前面的 insert 语句成功后,才取得自增值;要么使用判断的方式,循环判断前面的 insert 是否插入了新的自增值,才使用最新的自增值。不管是悲观锁还是乐观锁,都势必会降低入库性能。因此从性能角度来考虑,自增id浪费了就浪费了。

六、一条SQL语句在MySQL中是如何执行的?

首先,需要了解MySQL的层次结构。

  1. 连接层:最上层是一些客户端和连接服务。主要完成一些类似于连接处理、授权认证、及相关的安全方案。在该层上引入了线程池的概念,为通过认证安全接入的客户端提供线程。同样在该层上可以实现基于SSL的安全链接。服务器也会为安全接入的每个客户端验证它所具有的操作权限。
  2. 服务层:第二层服务层,主要完成大部分的核心服务功能, 包括查询解析、分析、优化、缓存、以及所有的内置函数,所有跨存储引擎的功能也都在这一层实现,包括触发器、存储过程、视图等。
  3. 引擎层:第三层存储引擎层,存储引擎真正的负责了MySQL中数据的存储和提取,服务器通过API与存储引擎进行通信。不同的存储引擎具有的功能不同,这样我们可以根据自己的实际需要进行选取
  4. 存储层:第四层为数据存储层,主要是将数据存储在运行于该设备的文件系统之上,并完成与存储引擎的交互。

SQL 语句的执行流程如下:

客户端请求 —> 连接器(验证用户身份,给予权限) —> 查询缓存(存在缓存则直接返回,不存在则执行后续操作) —> 分析器(对SQL进行词法分析和语法分析操作) —> 优化器(主要对执行的sql优化选择最优的执行方案方法) —> 执行器(执行时会先看用户是否有执行权限,有才去使用这个引擎提供的接口) —> 去引擎层获取数据返回(如果开启查询缓存则会缓存查询结果)
在这里插入图片描述
(图片来源:https://zhuanlan.zhihu.com/p/164519371)

七、MySQL的存储引擎区别?

1、InnoDB 支持事务,MyISAM 不支持事务,这也是 MySQL 将默认存储引擎从 MyISAM 变为 InnoDB 的重要原因之一。
2、InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MyISAM 会失败。
3、InnoDB 使用聚集索引,MyISAM 是非聚集索引。
聚集索引的数据文件存放在主键索引的叶子节点上,因此InnoDB必须要有主键,通过主键搜索效率更高。MyISAM 的索引与数据分离,是非聚集索引,不论是主键还是普通索引,它们与数据文件都是分离的。
4、InnoDB 不保存表的具体行数,执行 select count(*) 需要全表扫描,而 MyISAM 用一个变量保存整张表的行数,速度更快。多说两句,InnoDB 执行 select count(*) 时,会先把数据读出来,一行一行累加,最后返回总数据。所以,当数据越来越大时,语句就越来越耗时,但由于 InnoDB 自身的事务特点,即 MVCC 的原因,InnoDB 表很难知道数据总数。
5、InnoDB 最小的锁粒度是行锁,MyISAM 仅支持表锁,在并发访问的情况下效率太低。

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

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

相关文章

tcs标准编写软件_【公益培训】知你所需 | 标准编写格式及TCS模板应用线上公益培训...

企业标准编写的水平及TCS工具使用的能力是实施企业标准化工作的基础。TCS标准编写软件是辅助标准编写的工具性软件&#xff0c;方便标准编写人员快捷准确的编写标准草案&#xff0c;有效提升标准供给质量。为贯彻落实疫情防控和助力企业复工复产工作&#xff0c;山东标准化协会…

Linux进阶之路——常用命令总结

一、帮助命令 help man type区分内建、外建命令 【扩展】关于内建命令与外建命令。 内建命令属于shell程序的一部分&#xff0c;包含一些比较简单的Linux命令。这些命令被写在/bin/bash 文件的 builtins 里面&#xff0c;由shell程序识别并在shell程序内部完成运行。通常在Li…

bios设置 联想m8000t_怎么进bios设置硬盘启动顺序

操作说明&#xff1a;1、不同电脑进BIOS按键不一样&#xff0c;常见的有del、F1、F2、Esc、enter、F8、F9等2、在电脑启动时&#xff0c;不停按Del、F2等按键会进入BIOS设置界面&#xff0c;开机按哪个键进BIOS设置BIOS类型一&#xff1a;CMOS Setup Utility1、启动时按Del进入…

MySQL 基础 ————事务与隔离级别总结

引言 在处理并发读或写时&#xff0c;可以通过实现一个由两种类型的锁组成的锁系统来解决问题&#xff1a; 共享锁&#xff08;shared lock&#xff09;和排它锁&#xff08;exclusive lock&#xff09;&#xff0c;也叫读锁&#xff08;read lock&#xff09;和写锁&#xff0…

32f407tim4时钟源频率_慎重选择时钟发生器,别让这俩指标影响你的ADC 「图片」...

系统设计师通常侧重于为应用选择最合适的数据转换器&#xff0c;在向数据转换器提供输入的时钟发生器件的选择上往往少有考虑。然而&#xff0c;如果不慎重考虑时钟发生器的相位噪声和抖动性能&#xff0c;数据转换器动态范围和线性度性能可能受到严重的影响。系统考虑因素采用…

Spring —— IoC 容器详解

引言 本篇博客总结自官网的《The IoC Container》&#xff0c;其中会结合王富强老师的《Spring揭秘》融入自己的语言和理解&#xff0c;争取通过这一篇文章彻底扫除spring IOC的盲区。 本文介绍什么是 IoC 容器&#xff0c;什么是 Bean&#xff0c;依赖&#xff0c;Bean Defi…

nvidia控制面板点了没反应win7_win7系统Nvidia控制面板怎么设置?

许多用户不知道Nvidia控制面板怎么设置?那么Nvidia控制面板如何设置呢?其实设置的方法很简单。接下来&#xff0c;小编就把Nvidia控制面板设置的方法告诉大家。1、首先在桌面右键点击选择NVIDIA控制面板。2、显卡的设置性能肯定是要高好了&#xff0c;所以在性能设置方面&…

切割 字符串_web前端如何使用字符串

一、字符串概述定义&#xff1a;字符串就是用单引号或者双引号包裹起来的&#xff0c;零个或多个排列在一起的字符。例如&#xff1a;’javascript‘, “”, “345” , ’9-11a$‘, “xiao_yuanLian”嵌套&#xff1a;字符串可以嵌套。在单引号包裹的字符串内部&#xff0c;应该…

Redis 缓存实战——缓存、数据库一致性问题分析与解决方案

引言 缓存与数据库一致性的问题自从出现了缓存概念后就一直被提及&#xff0c;它是一个缓存方案的先天缺陷&#xff0c;只要存在缓存&#xff0c;就势必会讨论缓存与数据库一致性的问题。 一致性问题还广泛存在于各种分布式存储场景中&#xff0c;如主从一致性等等。 本篇博…

Java 多线程 —— AQS 详解

引言 AQS 是AbstractQuenedSynchronizer 的缩写&#xff0c;抽象的队列式同步器&#xff0c;它是除了java自带的synchronized关键字之外的锁机制。是 JUC 下的重要组件。 相关产物有&#xff1a;ReentrantLock、CountDownLatch、Semaphore、ReadWriteLock等。 一、AQS的设计…

的主机名_如何在Mac 上更改电脑的名称或本地局域网主机名?

我们知道&#xff0c;一台电脑有其设定的具体名称&#xff0c;电脑的名称和本地主机名用于在本地网络上识别您的电脑。当我们需要自定义电脑名称或本地局域网主机名时&#xff0c;则需要对其进行更改。那我们该如何更改呢&#xff1f;有需要的小伙伴们快和小编一起来看看吧~更改…

dev控件swiftplot图滚动方法_无限轮播图使用Scroller就这么简单

前言这几天又拾起老本行&#xff0c;复习复习Android&#xff0c;才发现忘的差不多了&#xff0c;上午做了一个小Demo&#xff0c;配合Scroller做了一个轮播图&#xff0c;效果如下&#xff0c;但是不知为何&#xff0c;录制的GIF成这样&#xff0c;凑乎一下看看。原理是继承Vi…

JVM——CPU缓存架构与Java 内存模型

导航一、CPU缓存架构与一致性协议1.1 CPU缓存架构1.2 缓存行与伪共享问题1.3 MESI 缓存一致性协议1.4 伪共享的解决办法二、JMM Java 内存模型2.1 JMM 简介2.2 原子性、可见性、有序性2.3 八大内存交互操作2.4 happens-before 原则一、CPU缓存架构与一致性协议 1.1 CPU缓存架构…

白噪声检测_科学家尝试用智能扬声器的白噪声来监测婴儿的呼吸运动

华盛顿大学的一支研究团队&#xff0c;刚刚介绍了他们开发的一种新型智能扬声器技术。这种设备能够借助白噪声来安抚熟睡的婴儿&#xff0c;并监测他们的呼吸和运动。具体说来是&#xff0c;通过智能扬声器发出的白噪声&#xff0c;原型设备能够将之与生命体征监测仪的数据相匹…

最大值_285期 博最大值2路,已经箭在弦上!

往期数据P-5掉码 跨度 和尾 012断路 余数和 位数86072 1 8 4 200 断1路2 5 对214对 双双双79703 0 2 3 101 断2路2 4 对215对 单单单62386 0 4 1 020 断1路2 4 错216对 双双单71903 0 8 7 110 断2路2 5 错217对 单单单64838 0 4 8 012 来3路3 4 错218对 双双双02052 0 2 2 020 …

商品领域ddd_为 Gopher 打造 DDD 系列:领域模型-资源库

前言&#xff1a; 作为领域模型中最重要的环节之一的Repository&#xff0c;其通过对外暴露接口屏蔽了内部的复杂性&#xff0c;又有其隐式写时复制的巧妙代码设计&#xff0c;完美的将DDD中的Repository的概念与代码相结合&#xff01;Repository资源库通常标识一个存储的区域…

mysql5.7主从全备恢复_Mysql5.7—运维常用备份方式(超全)

小生博客&#xff1a;http://xsboke.blog.51cto.com小生 Q Q&#xff1a;1770058260-------谢谢您的参考&#xff0c;如有疑问&#xff0c;欢迎交流一、 Mysqldump备份结合binlog日志恢复使用mysqldump进行全库备份&#xff0c;并使用binlog日志备份&#xff0c;还原时&#xf…

docker 运行容器_Docker之运行 Django 容器

首先此篇笔记默认你已经安装好了 Docker&#xff0c;并了解 Docker 的基础概念&#xff0c;诸如镜像、容器、以及他们之间的关系等。如果不太了解&#xff0c;等我回头了解清楚以后&#xff0c;可以再写一篇文章阐述一下。&#xff08;狗头当然&#xff0c;对于这篇文章&#x…

mysql8.0与mysql7.0_MySQL 5.7 vs 8.0,哪个性能更牛?

测试mysql5.7和mysql8.0分别在读写&#xff0c;选定&#xff0c;只写模式下不同并发时的性能(tps&#xff0c;qps)最早测试使用版本为mysql5.7.22和mysql8.0.15sysbench测试前先重启mysql服务&#xff0c;并清除os的缓存(避免多次测试时命中缓存)每次进行测试都是新生成测试数据…

springmvc使用requestmapping无法访问控制类_研究人员称人类使用的新烟碱类杀虫剂让蜜蜂无法入睡...

来自布里斯托尔大学的科学家进行了研究&#xff0c;显示常见的杀虫剂可以阻止蜜蜂和苍蝇睡个好觉。就像人类一样&#xff0c;许多昆虫也需要睡眠才能正常工作。然而&#xff0c;如果它们接触过新烟碱类杀虫剂&#xff0c;它们的睡眠就会受到影响&#xff0c;新烟碱类杀虫剂是一…