Mysql数据库相关面试题

news2025/2/21 19:54:03

1.关系型和非关系型数据库的区别是什么?

关系型和非关系型数据库的主要差异是数据存储的方式,关系型数据库天然就是表格存储,因此存储在数据表的行和列中,数据表可以彼此关联协作存储,很容易提取数据.

  • 优点:
    • 易于维护:都是使用表结构,格式一致,
    • 使用方便:sql语言通用,可以用于复杂查询
    • 复杂操作:支持sql,可用于一个表以及多个表之间非常复杂的查询.
  • 缺点:
    • 读写性能较差,尤其是海量数据高效读写,
    • 固定的表结构,灵活度稍差
    • 高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈.

与其相反的是非关系型数据库,他不适合存储在数据表中的行和列,而是大块组合在一起.非关系型数据通常存储在数据集中,就像文档,键值或者图结构.你的数据及特性是选择数据存储和提取方式的首要因素.

  • 优点:
    • 格式灵活:存储数据的格式可以是Key:value形式,文档形式,图片形式等等,使用灵活应用场景广泛,二关系型数据库则只支持基础类型.
    • 速度快:nosql可以使用硬盘或者随机存储器作为载体,二关系型数据库只能硬硬盘
    • 高扩容性,
    • 成本低:nosql部署简单,基本都是开源软件.
  • 缺点:
    • 不提供sql支持,学习和使用成本较高;
    • 无事务处理
    • 数据结构相对复杂,复杂查询方面稍差

/详细说一下一条SQL语句执行步骤

引用(SQL语句执行过程)

  • Server层按顺序执行SQL步骤为:
    • 客户端请求->连接器(验证身份,给予权限)
    • 查询缓存(存在缓存则直接返回,不存在则执行后续操作)
    • 分析器(对SQL进行词法分析和语句解析)
    • 优化器(主要是对执行的SQL进行优化,选择最优的执行方案)
    • 执行器(执行时会先看用户是否有执行权限,有的话才回去使用这个引擎提供的接口)
    • 去引擎层获取数据返回(如果开启查询缓存则会缓存查询结果,然后返回数据,如果没有开启缓存,那么就直接返回数据,)
    • 在这里插入图片描述

 3.Mysql使用索引的原因?

根本原因:

  • 索引的出现就是为了提高数据的查询效率,就像书的目录一样.
  • 对于数据库而言,索引其实就是他的目录

扩展

  • 创建唯一索引,可以保证数据库表中每一行数据的唯一性
  • 帮助引擎层避免排序和临时表
  • 将随机io变为顺序io,加速表和表之间的连接

4.索引的三种常见的底层数据结构以及优缺点是什么?

三种常见的索引底层数据结构:  哈希表,有序数组,搜索树

哈希表:

  •         使用场景一般是等值查询,比如redis,memcached 等键值存在1V1关系,不适合范围查询.
  • 有序数组:
  •         索引只适用于静态存储引擎,等值和范围查询性能较好,但是更新数据成本较高,(因为是有序数组,所以内存都是连续的.这种情况下如果中间插入数据的话会导致有序数组重新分配内存进行扩容操作.所以更适合读场景,追加写入场景应该也可以.但是不适用插入场景,)
  • N叉树:
  •         由于读写性能的优点以及适配磁盘访问模式所以广泛应用在数据库引擎中,
  • 扩展:

        以InnoDB的整数字段威力.这个N差不多是1200(跟一个数据页存储数据量大小有关.可以在系统初始化的时候调整数据页大小,来适配不同场景,这里要表达的是这个1200不是一个定数,而是可以优化的.默认16K)棵树高4的时候就可以存储1200的三次方个索引.约17亿.考虑到树根的数据块总是存在内存中的,一个10亿行的表上一个整数字段的索引,查找一个值最多需要3次IO即可查询到,其实书的第二层也有很大概率在内存中,那么访问磁盘的平均次数就更少.

5.索引的常见类型以及他是如何发挥作用的?

索引的常见类型分为主键索引和非主键索引.

  •         主键索引的叶子节点存储的是整行数据.在innodb里也成为了聚簇索引.
  •         非主键索引叶子节点存贮的是主键的值,在innodb里也叫作二级索引.

6.MyISAM和innodb实现B树索引方式的区别是什么?

  • innodb存储引擎:
    • B+tree索引的叶子节点保存的是数据本身,其 数据文件本身就是索引文件.
  • MyISAM存储引擎:
    • B+tree索引的叶子节点保存数据的物理地址.叶子节点的data域存放的是数据记录地址,索引文件和数据文件是分离的.

7.innodb为什么设计B+tree索引?

  • B+tree的层级更少:
    • 非叶子节点中存放的元素不存放数据,所以每一层可以容纳更多元素,这样磁盘中的每一页可以存放更多元素.这样在插查找的时候,磁盘IO的次数会更少.
  • B+tree查询速度更稳定:
    • 每次查找都必须匹配带叶子节点.因此每一次查找都是稳定的.(不会因为数据库的字段信息变大,二导致查询速度减缓,相同情况下,数据越多查询效率相比二叉树就越高,因为二叉树不光树高比N叉树高,而且索引会与数据存放在一起,所以在检索查询的时候要检索的数据量和IO次数会更大.)
  • B+tree天然具备排序功能:
    • B+tree所有的叶子节点数据构成一个有序的链表,在进行范围查询的时候更方便,数据紧密性高,缓存命中率也比较高.
  • B+tree全节点遍历更快:
    • B+tree遍历整棵树只需要遍历所有的叶子节点即可,不需要像B-Tree一样需要每一层进行遍历.有利于数据库做全表扫描
  • 因为B+tree底层维护了一个连表,所以进行区间查询的时候效率比较高,B-Tree在进行区间查询的时候需要使用中序遍历,效率是比B+tree要低一点
  • 所以综上所述 Mysql的Innodb引擎使用B+tree更有优势.

8.相比其他的索引方式为啥选择B+tree?

原因之一参考第4条,

  • 哈希索引虽然能提供O(1)复杂度查询,但是对范围查询和排序没有很好地支持,最终导致全表扫描.
  • B-Tree能够在非叶子节点存储数据,但是会导致在查询连续数据的时候带来更多的随机IO
  • 而B+tree的所有叶节点可以通过指针来相互连接,减少顺序遍历带来的IO.
  • 普通索引还是唯一索引如何选择??

    • 由于唯一索引用不上change  buffer的优化机制,因此如果业务可以接受,从性能角度来说优先考虑非唯一,(因为唯一索引需要在更新的时候必须保证数据的唯一性,所以每次更新都必须要写磁盘,所以磁盘IO无法避免,而二级索引没有唯一性要求,索引可以直接写change buffer用来提高读取数据的效率.)

9.什么是覆盖索引和索引下推?

  • 在一个查询中索引看已经覆盖了我们的查询需求(我需要查询的结果就是索引本身),成为覆盖索引.
  • 覆盖索引可以减少书的搜索次数,显著提升查询性能,索引使用覆盖索引是一个常用的优化手段.
  • 索引下推:
    •  Mysql5.6引入下推优化,(index condition pushdown),可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录.减少回表次数.

10.哪些操作会导致索引失效?

  • (关键原因是最左匹配原则,索引如果没法满足最左匹配原则的话就无法根据这个原则来优化索引查找.所以当条件不满足最左匹配原则的时候就没法走索引)
  • 对索引使用左或者左右模糊匹配,也就是like %xxx 或者like %xxx%这两种方式都会造成索引失败,原因在于查询结果可能是多个,不知道哪个索引值开始比较,于是就只能通过全表扫描方式来查询.
  • 对索引进行函数或者表达式计算,会导致索引失效,因为索引保持的是索引字段的原始值,而不是经过函数计算的值,自燃就没法走索引.
  • 对索引进行隐式转换相当于使用了新函数,(隐式转换的函数)
  • where子句中的OR语句,只要有条件列不是索引列,就会进行全表扫描,(因为有条件不是索引,所以查找的时候要根据主键先找到对应的条件,然后根据条件来进行二次筛选,所以这个过程需要全表扫描.)

11.字符串加索引的方式有哪些?利弊是什么?

  • 直接创建完整索引,这样因为字段长度可能比较长会非常占用空间(其实就是将字段的数据以索引的形式添加到树干结构中.)
  • 创建前缀索引.节省空间,但是会增加查询扫描次数,并且不能使用覆盖索引.因为是前置索引,所以只会将字符串中的前N个字符加载到索引中,所以不满足覆盖索引的条件.
  • 倒叙存储,再创建前缀索引,用于绕过字符串本身前缀的区分度不够的问题.(就是将字符串翻转后再做一个正向索引,取数据的时候再进行翻转将原本的数据恢复到正向,)

12.Mysql 的 change buffer 是什么?

  • 总结就是为了减少磁盘IO,专门设置的内存缓冲区.用于修改操作.只有触发一定的条件后才会集体写磁盘.
  • 当需要更新衣蛾数据页的时候,如果数据页在内存中的话那么就直接更新,然后返回给用户,以下情况会触发磁盘写入:
    • 当访问这个数据页的时候,
    • 后台master线程会定期merge数据,这个去取决于相关参数的设置.
    • 数据库缓冲池不够用时.
    • 数据库正常关闭时.
    • redo  log写满时,(本身就是个循环写入的内存,当写完一周就会从最先写入的数据进行刷盘.)
  • 如果这个数据页还没有在内存中的话,在不影响数据一致性的情况下,innodb会将这些更新操作缓存在change buffer中.
  • 适用场景:
    • 对于写多读少的业务来说,页面在写完以后马上被访问到的概率很小的情况下,适用change buffer 是比较好的.这样就不用频繁就该磁盘数据.来获取最新修改的值,
      • 例如 账单,报表, 日志等系统.
    • 相反如果读多写少的话,就不适应,因为频繁读取数据会导致这个缓冲区存在的意义失效,buffer中的数据需要与磁盘中的数据保持一致,所以当在触发读取数据页操作的时候,这块修改好数据就会刷盘.然后被用户读出.buffer参与的时间非常少(甚至没有参与.)

13.mysql是如何判断查找到一行数据扫描了多少行数据的?

引用(查看mysql索引区分度_mysql 索引信息查看)

  • 在语句执行前并不能精确的知道满足这个条件的记录有多少.
  • 而只能根据统计信息来估算记录数,这个统计信息就是索引的区分度,
    • 当我们需查查看表中索引信息时,可以直接使用show index from `表名`
    • 或者使用explain查看一下当前sql的执行计划,来判断是否是用了索引.

14.Mysql的redo log 和binlog的区别是什么?

redo logbinlog
作用用于服务崩溃后数据恢复(写入成功但是没完成刷盘操作的数据)主从复制和数据恢复
实现方式innodb存储引擎实现,Server层实现,所有的存储引擎都可以使用binlog.
记录方式        循环写入方式,记录的是sql语句本身,写到结尾的时候会回到开头重新使用之前的内存空间写入新数据,最先写入的数据会按照顺序写入到数据表中.(落盘)通过追加的方式记录,记录的内容跟日志记录级别有关,row记录的是每一行数据锁形成的sql语句,语句及会记录一条完整的批量操作语句.当文件的尺寸大于给配置的值后,后续的文件会写入到一个新的文件中.
文件大小redo log大小是固定的(一部分在内存中 redo log buffer 一部分在磁盘中(顺序追加写入所以写入速度较快),磁盘中的叫redo log file)通过配置参数 max_binlog_size设置每一个binlog文件切割大小.

crash-safe能力        

具有不具有(因为)
日志类型逻辑日志(就是)物理日志

15.为什么需要redo log

  • redo log 主要用于MySQL异常重启后的一种数据恢复手段,确保了数据的一致性.
  • 其实是为了MySQL的wal机制,(就是预写日志系统,就是先写日志,成功了之后再写数据让数据落盘)因为MySQL进行更新操作.为了能够快速响应,所以采用了异步写回磁盘的技术.写入内存后就返回给用户,但是如果在完成内存写入后发生系统故障没有完成落盘操作.那么redolog是具备crash safe的能力的.()

16.undo log 的作用是什么?

14-16引用(MySQL的WAL机制)

  • undo log撤销,回滚。当事务回滚或者数据库崩溃的时候,可以利用undo log撤销未提交的事务对数据库产生的影响。
  • undo log产生和销毁:在事务开始前产生;事务在提交时,并不会立刻删除undo log,innodb会将该事物对应的undo log放入到删除列表中,后面会通过后台线程purge thread进行回收。undo log属于逻辑日志,记录一个变化过程。例如执行一个delete语句,undo log会记录一个insert。
  • undo log 存储:undo log采用段的方式进行管理和记录。在innodb数据文件中会包含一种rollback segment 回滚段,内部包含1024个undo log段。

作用:

  1. 实现事务的原子性
  2. 实现多版本并发控制(MVCC):事务未提交之前,undo log 保存了未提交的之前的版本数据,undo log 中的数据可作为数据旧版本快照供其他并发事务进行快照读,相当于做了 一个备份。

17.为什么redo log 具有crash-safe能力?binlog无法代替?

  • redo log 可以知道innodb哪些数据已经刷盘,哪些数据还没.
    • redolog和binlog有一个很大的区别就是一个是循环写入数据一个是追加写入数据.也就是说redolog只会记录为刷盘的日志.已经写入的数据会从redo log中 删除.binlog是追加写入.保存额是全量日志.
    • 当数据crash后,想要恢复未刷盘单已经写入redolog和binlog的数据到内存时,binlog是无法恢复的.虽然binlog拥有全量日志.但是没有一个标志让innodb知道哪些数据是已经刷盘完成的.哪些是未刷盘完成的.
    • redo log不同,只要是刷盘成功的数据会从redo log中抹掉,因为是循环写,数据库重启后,直接将redolog中的数据全量恢复即可.恢复的过程中也会追加binlog的日志写入.
  • 如果redo log 写入失败.说明此次操作失败.事务也不可能提交.
    • redolog每次更新操作完成后,就一定会写入日志,如果写入失败,说明此次操作失败.事务不会提交,
    • redolog 内部结构是基于数据页的,记录了这个也的字值变化,只要crash后读取redolog进行重放,就可以恢复数据.
    • 这就是为什么redolog具备carsh-safe能力,而binlog不具备.

18.当数据库crash后如何恢复未刷盘的数据到内存中?

  • 根据 redo log 和 binlog 的两阶段提交,未持久化的数据分为几种情况:
    • change buffer 写入,redo log 虽然做了 fsync 但未 commit,binlog 未 fsync 到磁盘,这部分数据丢失。
    • change buffer 写入,redo log fsync 未 commit,binlog 已经 fsync 到磁盘,先从 binlog 恢复 redo log,再从 redo log 恢复 change buffer。
    • change buffer 写入,redo log 和 binlog 都已经 fsync,直接从 redo log 里恢复。

      写入逻辑
      • 将旧数据记录到 undo log 中以便于回滚时候重做.
      • 将新的更改记录到redo log buffer 中.并fsync到磁盘的日志文件中,状态改为pre pare,
      • 将逻辑操作记录到binlog cache中,并fsync到磁盘日志文件中.
      • 设置redo log 的记录为commit.
      • 最后返回给用户修改成功.

19.redo log 写入方式

redo log包括两部分内容,分别是内存中的日志缓冲(redo log buffer)和磁盘上的日志文件(redo log file)。

 MySQL 每执行一条 DML 语句,会先把记录写入 redo log buffer(用户空间) ,再保存到内核空间的缓冲区 OS-buffer 中,后续某个时间点再一次性将多个操作记录写到 redo log file(刷盘) 。这种先写日志,再写磁盘的技术,就是WAL。

  • 可以发现,redo log buffer写入到redo log file,是经过OS buffer中转的。其实可以通过参数
    • innodb_flush_log_at_trx_commit进行配置,参数值含义如下:
    • 0:称为延迟写,事务提交时不会将redo log buffer中日志写入到OS buffer,而是每秒写入OS buffer并调用写入到redo log file中。
    • 1:称为实时写,实时刷”,事务每次提交都会将redo log buffer中的日志写入OS buffer并保存到redo log file中。
    • 2:称为实时写,延迟刷。每次事务提交写入到OS buffer,然后是每秒将日志写入到redo log file。

20.redo log 的执行流程是什么?

参考18条

  • MySQL客户端将请求语句update T set a =1 where id=666,发往MySQL server 层 
  • MySQL server 层收到sql 请求后,对其进行分析,优化,执行处理工作.将生成的sql执行计划发到innodb存储引擎层进行执行.
  • innodb存储引擎将a修改为1的这个操作存储到内存中,并将逆向操作记录到undolog日志中
  • 记录到内存以后会修改redo log 的记录会在添加一行记录,其内容是急需要在哪一个数据页上做什么修改,
  • 伺候将事务的状态设置为prepare,说明已经准备好提交事务了,
  • 等到MySQL server层处理完事务以后,会僵尸舞的状态设置为commit.也就是提交该事务.
  • 在收到事务提交请求后,redo log 会吧刚刚写到内存中的操作记录写到磁盘中.而完成整个日志的记录过程.

21.binlog 的概念是什么?起到什么作用?可以保证crash-safe吗?

  • binlog是归档日志,属于MySQLserver层的日志.可以实现主从复制,和数据恢复两个作用.
  • 需要回复数据是,可以取出某个需要回复的时间范围内的数据进行重放操作.将原本执行过的操作重新执行以下,就可以实现数据恢复.
  • 但是binlog 是 无法做crash-safe的,因为crase之前,binlog可能没有完全写入MySQL语句就挂了.所以需要配个redo log 才可以进行crash safe操作.

22.什么是两阶段提交?

MySQL将redo log 的写入拆成两个步骤.prepare 阶段和commit 阶段.中间在穿插写入binlog. 这就是两阶段提交.(参考18条,20条.)

 而两阶段提交就是让这个状态保持逻辑上的一致.redo log 用于恢复主机故障时的未更新屋里数据.,binlog 用于备份操作.两者本身就是两个独立的个体.想要报纸一致,就必须使用分布式事务的解决方案来处理.

为什么需要两阶段提交呢?

  • 如果不使用两阶段提交的话可能会出现以下几种情况.
    • 先写redo log ,当crash 后binlog备份恢复时少了一次更新,当前数据会导致不一致.在于其他机器进行数据同步的时候会导致数据不同步的情况发生.
    • 先写binlog ,当crash 后由于redo log 没写入.事务无效.所以后续binlog 备份恢复的时候,数据会不一致.(同样会在主从数据同步的时候导致数据不一致.因为主库可能没有某些数据,但是写了binlog 导致丛库重放操作的时候,将某些数据错误写入.)
    • 两阶段提交就是为了保证 redo log和binlog 的数据安全一致性,只有这两个日志文件逻辑上高度一致了,才能保证数据安全,
  • 在恢复数据时,redo log 为commit的说明binlog的数据已经写入成功,直接进行数据恢复即可,.如果redo log是parpare状态.则需要查询对应的binlog事务是否成功,决定是回滚还是执行

23.MySQL 怎么知道 binlog 是完整的?

  • 一个事务的binlog 是有完整格式的:
    • statement 格式的binlog,最后会有commit,(语句及记录方式)
    • row 格式的binlog,最后会有一个XID event.(行级记录方式(一般都是行级))

24.什么是WAL技术,有什么有点?

  • WAL,中文全称Write-Ahead logging 意思是先写日志,再写磁盘,MySQL执行更新操作后,在真正把数据写入到磁盘前,先记录日志.
  • 好处是不用每次操作都实时吧数据写磁盘,就算crash后也可以根据redo log 进行数据恢复.所以能够实现快速响应SQL语句.

25.binlog 三种记录模式是什么?

  • Statement : 基于SQL语句的复制
    • 优点:语句级模式.记录操作时候的sql语句.这种记录方式节省IO操作,提高性能,
    • 缺点:如果主库使用了某些类似于now(),或者last_inster_id(),sleep()这样的函数,那么就会导致主从库数据不一致.
  • Row:基于行的复制行级模式,
    • 将一个范围操作拆分成每一行的操作,记录更加精确.不会出现数据不一致的情况,
    • 缺点就是每一行都会有一个记录的sql 语句.这种情况会占用大量的存储空间.
  • Mixed:混合复制模式
    • 将部分ddl和一些函数操作使用statement模式进行日志记录.如果是dml那么还是会记录所有行的变更.

26.redo log 日志格式

 redo log buffer (内存中)是由首尾相连的四个文件组成,他们分别是:ib_logfile_0, ib_logfile_1,ib_logfile_2,ib_logfile_3

  • write pos 是当前记录的位置,一边写一边向后移动,写到第3号文件末尾后就回到0号文件开头,
  • chenkpoint 是当前要擦除的位置,也是往后推移并循环的,擦除记录要提前吧记录更新到数据文件.
  • write pos 和check point支架你是粉板,上面空着的部分可以用来记录新的操作.
  • 如果wirte pos追上checkpoint,表示粉板满了,这时候不能在执行新的更新,得停下来先擦掉一些记录.把checkpoint推进一下.
  • 有了redolog 当数据库发生宕机重启后,可以通过redo log将为落盘的数据(checkpoint之后的数据)进行恢复,保证已经提交的事务记录不会丢失,这种能力叫做crash-safe.

27.原本可以执行得很快的 SQL 语句,执行速度却比预期的慢很多,原因是什么?如何解决?

原因:从大到小可以分成4中情况

  • MySQL数据库本身堵住了,比如:系统或者网络资源不够.
  • SQL语句被堵住了,比如锁表,行锁,导致存储引擎不执行对应的SQL语句,
  • 确实是索引使用不当,没有索引.
  • 表中数据的特点导致,走了索引,但是回表次数太多.

解决:

  • 考虑采用force index 强制选择一个索引
  • 修改语句,引导MySQL使用我们期望的索引,比如把order by b limit1 修改成 order by b,a limit 1,语义的逻辑 相同,但是有可能会用到a字段索引,
  • 新创建一个更合适的索引,来提供优化器做选择.或者删除误用的索引.
  • 如果确定是索引根本没有使用到的话,可以直接将索引删除.

28.innoDB数据页结构是什么?

一个数据页大致分成7个部分

  • File Heaner:表示也的一些通用信息.占固定的38个字节.
  • page Header:表示数据页转悠信息,占固定的56字节,
  • inimum+Supermum:两个虚拟的伪记录,分别表示页中的最小记录和最大记录,占用26字节.
  • Use Records:真正存储我们插入的数据,大小不固定.
  • Free Space: 页中尚未使用的部分,大小不固定,
  • Page DIRctory: 页中某些记录的相对位置.也就是各个曹对应的记录在页面中的地址偏移量.
  • File Trailer: 用于检验页是否完整,占用8字节.

28.MySQL是如何保证数据不丢失的?

  • 只要redolog 和binlog 保证持久化磁盘就能确保MySQL异常重启后可以恢复数据.
  • 在恢复数据时,redo log状态为commit的则说明binlog也是成功的.直接进行数据恢复即可.如果redo log 是prepare,则需要查询对应的binlog事务是否成功,决定是否回滚还是执行.

29.如果误删了数据怎么办?

DBA最核心的工作就是保证数据完整性,先做好预防,预防的话大概是通过以下几点:

  • 权限控制与分配(数据库和服务器权限.)
  • 制作操作规范.
  • 定期开发培训.
  • 搭建延迟备库.
  • 做好SQL审计.只要是对线上数据库有更改操作的语句(DML和DDL)都需要进行审核.
  • 做好备份,备份又分为两点
    • 1,如果数据量很大的话,可以使用xtrabackup进行物理备份.定期对数据库进行全量备份,也可以做增量备份,
    • 2,如果数量比较少,使用mysql dump 或者mysqldumper 进行逻辑备份.再进行binlog来恢复或者搭建主从的方式来恢复数据.定期备份binlog文件也是很有必要的.
  • 如果发生数据删除的操作那么可以从以下几点进行恢复:
    • DML误操作语句造成数据不完整或者丢失,可以通过flashback,美团的myflash,进行数据恢复.操作方式都是先解析binlog,然后通过语句翻转进行数据恢复.比如delete翻转成insert,或者insert翻转成delete,update进行前后对调.
  • 所以必须设置binlog_format=row,binlog_row_image=full,切记数据恢复的时候,应该先恢复到临时实例,然后再恢复住数据库.
  • DDL语句误操作(truncate和drop),由于DDL语句不管 binlog_format 是 row 还是 statement ,在 binlog 里都只记录语句,不记录 image 所以恢复起来相对要麻烦得多。
  • 只能通过全量备份+应用 binlog 的方式来恢复数据。一旦数据量比较大,那么恢复时间就特别长
  • rm 删除:使用备份跨机房,或者最好是跨城市保存
     

30.drop delete,truncate的区别是什么?

  • DELETE 语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存以便进行进行回滚操作。
  • TRUNCATE TABLE 则一次性地从表中删除所有的数据并不把单独的删除操作记录记入日志保存,删除行是不能恢复的。并且在删除的过程中不会激活与表有关的删除触发器。执行速度快。
  • drop语句将表所占用的空间全释放掉。
  • 在速度上,一般来说,drop> truncate > delete。
  • 如果想删除部分数据用 delete,注意带上 where 子句,回滚段要足够大;
  • 如果想删除表,当然用 drop;如果想保留表而将所有数据删除,如果和事务无关,用 truncate 即可;
  • 如果和事务有关,或者想触发 trigger,还是用 delete;如果是整理表内部的碎片,可以用 truncate 跟上 reuse stroage,再重新导入/插入数据。

31.在MySQL中的两个kill有什么不同?

  • 一个是 kill query + 线程 id,表示终止这个线程中正在执行的语句
  • 一个是 kill connection + 线程 id,这里 connection 可缺省,表示断开这个线程的连接

kill 不掉的原因

  • kill命令被堵了,还没到位
  • kill命令到位了,但是没被立刻触发
  • kill命令被触发了,但执行完也需要时间

32.如何理解MySQL的边读边发?

  • 如果客户端接受慢,会导致MySQL服务端由于结果发布出去,这个事务的执行时间会很长,
  • 服务端并不需要保存一个完整的结果集.取数据和发数据的流程都是通过一个nex_buffer操作的.
  • 内存数据页都是在buffer_pool中操作的.
    • innodb管理buffer_pool使用的是LRU算法,使用连表实现,是线上,按照5:3的比例把整个LRU表分成young区域和old区域.

33.MySQL的大表查询为什么不会爆内存?

  • 由于MySQL是边读边发的,所以对于数据量很大的查询结果来说,不会在server端保存的结果集.所以如果客户端读结果不及时,会堵住MySQL的查询过程,但是不会把内存打爆.
  • innodb引擎内部.由于有淘汰策略,innodb管理buffer_pool使用的是改进的LRU算法,使用链表实现,实现上按照5:3的比例把整个LRU链表分成了young区域和old区域.对冷数据的全扫描,也能也能做到可控.

34.MySQL临时表的用法和特性

当会话结束,即连接关闭时MySQL会自动将创建的临时表执行删除操作

  • 1:语法是create temporary table ...
  • 2:临时表在会话之间是隔离的,即本会话只能看到本会话内创建的临时表
  • 3:临时表可以和普通表同名
  • 4:操作时,存在同名的临时表和普通表时,临时表的优先级高于普通表
  • 5:show tables不会显示临时表,只显示普通表
  • 6:不同会话可以创建同名的临时表

35.MySQL存储引擎介绍(innodb,MyISAM,MEMORY)

  • innodb是事务型数据库的首选引擎,支持事务安全表(ACID),支持行级锁定和外键,MySQL5.5.5之后innodb是MySQL默认的存储引擎.
  • MyISAM存储 引擎,有较高的插入速度和查询速度但是不支持事务,在MySQL5.5.5之前是MySQL的默认存储引擎.
  • MEMORY存储引擎是内存型的存储引擎,将表中的数据存储到内存中,为查询和引用其他表提供快速访问.

36.都说innodb好,那还要不要使用memory引擎?

  • 内存表使用的就是memory引擎建立的表.
  • memory表主要问题是锁粒度问题和数据持久化问题无法得到解决.
  • 由于重启会丢数据,如果一个备库重启,会导致主备数据库的同步线程停止;如果主库跟这个备库是双M架构,还可能导致数据库的主库的内存表被删除.(A<==>B互为主库.相互同步数据.)

37.如果数据库误操作,如何恢复数据?

  • 数据库在某个时候误操作,就可以找到距离误操作最近的时间节点的binlog,重放到临时数据库里,然后选择误删的数据节点恢复到线上数据库

38.MySQL是如何保证主备同步的?

主备关系的建立

  • 一开始创建主备关系的手,是由备库指定的,比如给予点位的主备关系,备库说我要从宾隆文件A的位置P开始同步,主库就从这个指定的位置开始往后发.
  • 而主备关系搭建之后,是主库决定要发给数据给备库的,所以主库有新的日志也会发给备库.

MySQL主备切换流程:

  • 客户端读写都是直接访问A,而节点B是备库,只要将A的更新都同步过来,到本地执行就可以保证数据是相同的,
  • 当需要切换的时候就把节点切换一下.

一个事务完整的同步过程:

  • 备库B和主库A建立了长连接,主库A内部专门线程用于维护这个长连接.
  • 在备库B上通过changemaster命令设置主库A的IP端口用户名密码以及从哪些位置开始请求binlog包括文件名称和日志偏移量.
  • 在备库B上start-slave命令备库会启动两个线程,IO_thread和sql_thread分别负责简历连接和读取中转日志进行解析执行.
  • 备库读取主库传过来的binlog文件,备库收到文件写到本地成文中专日志.
  • 后来由于多线程复制方案引入,sql_thread演化成了多个线程.

39.什么是主备延迟?

主库和备库在执行同一个事务的时候出现的时间差的问题.主要原因有:

  • 有些部署条件下,被困所在的机器的性能比主库差
  • 备库压力比较大.
  • 大事务,一个主库上语句执行10分钟,那么这个事务可能会导致丛库延迟10分钟.

40.为什么要有多线程复制策略?

  • 因为单线程复制能力全面低于多线程复制,对于更新压力较大的主库,备库可能一直追不上主库,带来的现象就是seconds_behind_master越来越大.
  • 在实际应用中,建议使用可靠性优化策略,减少主备延迟,提升系统可用性,尽量减少大事务,把大事务拆分成小事务.

41.MySQL的并行策略有哪些?

  • 按表分发策略:如果两个事务更新不同的表,那么他们就可以并行,因为数据是存储在表里的,所以按表分发可以保证两个worker不会更新同一行,缺点:如果碰到热点表,比如所有的更新事务斗湖涉及到某一个表的时候,所有事物都会被分配到一个worker中,就变成单线程复制了.
  • 按行分发策略:如果两个事物没有更新同一行数据,在他们的备库上可以并行执行,如果两个事物没有更新相同的行,他们在备库上可以并行执行,显然这个模式要求binlog记录格式必须是row才可以,缺点:相比于按表分发策略再决定线程分发的时候,需要消耗更多的计算资源.

42.MySQL的一主一备和一主多从有什么区别?

  • 在一主一备的双M架构里,主备切换只需要吧客户端流量切换到备库即可,主备之间都是可以直接写入数据的.
  • 而在一主多从架构里.纸杯切换除了要把客户留了切换到备库之外,还需要把丛库接到新主库上.(需要实现新的主库有写入数据的能力,并且其他丛库可以从新的主库上同步数据的能力才可以,)

43.MySQL 读写分离涉及到过期读问题的几种解决方案?

由于主从延迟的问题,从库的读取到的结果可能是旧的

有几种解决方案:

  • 强制走主库方案
  • sleep方案
  • 判断主备无延迟方案
  • 配合semi-sync方案
  • 等主库典韦方案
  • GTID方案
  • 实际生产中,先客户端对请求做分类,区分哪些请求可以接受过期读的情况,而哪些请求完全不能接受过期读,然后对于不能接受过期读的语句在使用等GTID或等点位方案.

引用(MySQL数据库如何解决主从缝里带来的过期读问题?)

44.MySQL的并发连接和并发查询有什么区别?

  • 在执行show processlist 的结果里面,看到几千个连接,指的是并发连接,而当前执行查询的SQL语句才是并发查询.
  • 并发连接数多影响的是内存,并发查询太高对CPU不利,一个机器的CPU核心数优先,线程全冲进来,上下文切换的成本就会很高.
  • 所以需要设置参数:innodb_tread_coucurrency用来限制线程数,当线程数达到该参数,innodb就会人为线程数用完了,会阻止其他语句进入引擎执行.

45.短时间提高MySQL性能的方法有哪些?

  • 第一: 先处理掉那些占着连接但是不工作的线程, 或者再考虑断开事务内空闲太久的连接 使用命令 show processlist  进行线程查看,使用  kill connection+id ,不工作的线程杀掉.
  • 第二: 减少连接过程的消耗,慢查询性能问题在MySQL中.会引发性能问题的慢查询.大体有一下三种可能性:
    •         索引没有设计好
    •         SQL语句没写好
    •         MySQL选错了索引(force index)

 46.为什么MySQL自增主键id不连续?

  • 唯一键冲突
  • 事务回滚
  • 自增主键的批量申请
  • MySQL不判断自增主键是否存在.而减少加锁时间范围和粒度.这样能保持更高的性能,确保自增主键不能退回.所以才有自增主键不连续的情况
  • 自增主键怎么做到唯一性?
  •         自增值+1操作是通过自增锁来控制并发的.

47.innodb为什么要用自增ID作为主键?

  • 自增主键的插入模式符合递增插入,每次都是追加操作,不涉及挪动数据,也不会触发叶子结点的分裂.
  • 每次插入新纪录就会顺序添加到当前索引节点的后续位置,当一页写满就会自动开辟一个新数据页.
  • 而有业务逻辑的字段做主键,不容易保证有序插入,(业务逻辑所生成的主键每次的生成的值都近似一个随机)
  • 因此每次新纪录都要被插到现有索引页的中间某个位置.会导致频繁的移动数据,分页操作造成大量的碎片,导致最终的数据结构不紧凑,;浪费存储空间,写入成本高.

48.grant和flush privileges语句的区别是什么?

  • grant会同时修改数据表和内存,判断权限的时候使用的内存数据,因此,范围使用是不需要加上flush privileges语句的.
  • flush privileges 语句本身会用数据表的书记重建一份内存权限数据.所以在权限数据可能存在不一致的情况下使用.

49.join用法

  • 使用left join左边的表不一定是驱动表
  • 如果需要left join的语义就不能把驱动表的字段放在where条件里面做等值判断或者不等值判断.必须写在on里面,
  • 标准的group by语句是需要在select部分加一个聚合函数.比如,select 啊 count(*) from t group by a order by null;

50.什么是幻读?

引用(幻读是什么, 幻读有什么问题)

  • 值在同一个事务中,存在前后两次查询同一个范围的数据,第二次看到了第一次没有查询到的数据.
    • 幻读出现的场景:
    • 事务的隔离级别是RR,可重复读,切实当前读.
    • 幻读值新插入的行数据,(第一次没有这行数据,但是在第二次读取相同范围操作的时候就出现了这条数据.)仅仅适用于插入操作.
  • 幻读带来的问题是什么?
    • 首先是语义上的. 前一次查询已经声明要加锁的行、不许别的事务进行读写操作, 而幻读却破坏了这个语义.
    • 是数据一致性的问题. 锁的设计是为了保证数据的一致性. 这个一致性、不止是数据库内部数据状态此刻的一致性、还包含了数据和日志在逻辑上的一致性.
  • 如何解决幻读问题?

    • 产生幻读的原因是: 行锁只能锁住行、但是新插入记录这个动作、要更新的是记录之间的间隙、为了解决幻读、就引入了间隙锁(Gap Lock).

56.为什么MySQL会抖一下?

  • 脏页会被后台线程自动flush,也会由于数据页淘汰而触发flush,而刷脏页的过程由于会占用资源,可能会让你的更新和查询语句相应时间会长一些.

57.为什么数据删掉了但是底层文件大小却几乎没有变化?

(说明一下,大多数使用orm进行MySQL操作的场景不会使用物理删除.只会将要删除的项目打一个标记.delete_time那么在查找数据的时候会排查这个字段是否为空,如果为空那么表示数据没有删除.如果不为空表示该数据已经被逻辑删除.无法返回给用户.),

  • 主要是原因是MySQL使用的是共享表空间还是独立表空间,
    • 如果是共享表空间的话,当数据删除了之后,删掉的数据会将数据空间空出来.给其他的数据进行复用,这里的删除操作是innodb 在某个数据页标记为可服用.
    • delete命令 把整个表的数据删除.结果就是所有数据页都会被标记上可复用.但是在底层的磁盘层面看到的就是数据文件没有变小.
    • 经过大量增删改的表会存在大量的空洞.这些空洞也会占用空间,所以重建表就可以将原来的空洞填不上.降低占用空间.
    • 如果是独立表空间的话删除表数据的话那么对应的底层文件(.ibd文件)也会被删除.
  • 使用 innodb_filer_per_table参数来控制
    • 如果是OFF ,表示存在系统表空间中和数据字典一起.
    • 如果是ON,每个innodb表结构都会存在以.idb为后缀的文件中.

58.count(*)实现方式以及各种 count 对比

  • 对于count(主键)来说,innodb引擎会遍历整张表.把每行的id值都取出来,返回给server层,server层拿到id后,然后按行累加.
  • 对于count(1)来说,innodb遍历整张表,但是不取值,server层对于返回的每一行,放一个数字1 进去,判断不是空的按行累加,但看这两个用法的差别的话mcount(1)执行要比count(主键id)快,因为引擎返回id会设计到解析数据行,以及拷贝字段值的操作.
  • 对于count(字段来说),如果这个字段是定义为notnull的话,一行行的从记录里面读出这个字段,判断不能为null,按行累加,
    • 如果这个字段定义为允许为null,那么执行的时候判断到有可能是null,还要把值取出来再判断一下.不是null才能累加.也就是前面的第一条原则,server要什么字段,innodb就返回什么字段.
  • 但是count(*)除外,并不会将全部字段取出来,而是专门做了优化,不取值,count(*)肯定不是null,按行累加,
  • 所以最终的结论是: 按照效率排序的话
  • count(字段)<count(主键id)<count(1)≈count(*).
  • 一般情况下直接使用count(*)就行.

59.orderby 内部排序原理是什么?

  • MySQL会为每个线程分配一个内存(sort_buffer)用于排序该内存大小为 sort_buffer_size;
  • 如果排序数据量小于sort_buffer_size,排序就会在内存完成.
  • 内部排序分为两种:
    • 全字段排序,到索引树上找到满足条件的主键ID根据主键ID去取出数据放到sort_buffer然后进行快速排序,
    • rowud 排序:通过控制排序的行数据的长度来让sort_buffer中尽可能多的存放数据;
  • 如果数据量很大,内存放不下,那么就会使用磁盘临时文件来辅助排序,成为外部排序,
    • 外部排序,MySQL会分为好几分单独的临时文件来存放排序后的数据,一般是磁盘文件中进行归并,然后将这些文件并拢成一个大文件.

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

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

相关文章

MyBatis逆向工程和分页插件

1、分页插件 MyBatis 通过提供插件机制&#xff0c;让我们可以根据自己的需要去增强MyBatis 的功能。需要注意的是&#xff0c;如果没有完全理解MyBatis 的运行原理和插件的工作方式&#xff0c;最好不要使用插件&#xff0c; 因为它会改变系底层的工作逻辑&#xff0c;给系统带…

2022年全国职业院校技能大赛:网络系统管理项目-模块B--Windows样题7

初始化环境1.默认账号及默认密码 Username: Administrator Password: ChinaSkill22! Username: demo Password: ChinaSkill22! 注:若非特别指定,所有账号的密码均为 ChinaSkill22! 项目任务描述你作为技术工程师,被指派去构建一个公司的内部网络,要为员工提供便捷、安…

超算云平台在线功能Q-Flow、Q-Studio V2.1版本升级,web端在线建模+DFT计算

建模DFT计算还可以这么玩&#xff1f; Q-Flow&#xff08;在线可视化提交任务功能&#xff09;以及 Q-Studio&#xff08;在线建模功能&#xff09;依托Mcloud平台免费向用户开放使用。告别Linux编辑代码提交任务的模式&#xff0c;Q-Flow可在浏览器里通过拖拽图形化的第一性原…

【第06节】Selenium4 JavaScript 处理场景实战(Python Web自动化测试)

Selenium 4 【01-06节】主讲元素定位&#xff0c;处理一些特殊场景的方法与实战已经全部写完。文章所有素材来自互联网&#xff0c;如果文章有侵权处&#xff0c;请联系作者。 文章目录1、Selenium4 自动化 JavaScript 场景实战1.1 使用 JavaScript 处理富文本1.2 使用 JavaScr…

Linux——网络编程总结性学习

什么是ISP&#xff1f; 网络业务提供商_百度百科 计算机网络有哪些分类方式,计算机网络有哪些分类&#xff1f;_陈泽杜的博客-CSDN博客 路由器_百度百科 目前实际的网络分层是TCP/IP四层协议 当我们浏览⽹站找到想要下载的⽂件以后&#xff0c;找到相应的接⼝点击下载就好了。…

新形势下安全风险评估实践

​ 随着安全内涵的不断扩充和发展&#xff0c;风险评估作为安全管理的重点&#xff0c;内容以及方法都与时俱进的得到了发展和丰富&#xff0c;本文将介绍新形势下风险评估的特点和实践心得&#xff0c;以供参考。 一、新形势下安全风险评估特点 首先是内外部形势和要求的变…

Docker入门教程(详细)

目录 一、Docker概述 1.1 Docker 为什么出现&#xff1f; 1.2 Dorker历史 1.3 能做什么 虚拟机技术&#xff1a;&#xff08;通过 软件 模拟的具有完整 硬件 系统功能的、运行在一个完全 隔离 环境中的完整 计算机系统&#xff09; 容器化技术&#xff1a;&#xff08;容…

【JAVA高级】——玩转JDBC中的三层架构

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java案例分…

Oracle SQL执行计划操作(8)——视图与集合相关操作

8. 视图相关操作 该类操作与包含视图的SQL语句相关。当SQL语句被硬解析时,如果SQL语句中的视图未被合并,则根据不同的具体场景,如下各操作可能会出现于相关SQL语句的执行计划。 1)VIEW 创建数据的一个中间视图,一般分为系统视图和用户视图。优化器在为SQL语句生成执行计…

iOS上架流程详细版本

苹果上架审核周期长一直是困扰用户的一大问题&#xff0c;这次把我自己上架的经历分享给大家&#xff0c;避免大家入坑。 上架总流程&#xff1a; 创建开发者账号 借助辅助工具appuploader创建证书&#xff0c;描述文件 iTunes connect创建App 打包IPA上传App Store等待审…

Kubernetes(k8s)CNI(flannel)网络模型原理

一、概述 Kubernetes 采用的是基于扁平地址空间的、非NAT的网络模型&#xff0c;每个Pod有自己唯一的IP地址。网络是由CNI(container network interface)插件建立的&#xff0c;而非K8S本身。 二、常见的几种CNI插件介绍 为了使容器之间的通信更加方便&#xff0c;Google 和 Co…

计算机网络面试大总结

本文分文五大部分&#xff0c;第一部分总纲说明计算机网络层次划分的三种模型&#xff0c;一到四部分以TCP/IP协议模型作为划分标准&#xff0c;分别说明各层作用和最常见的面试题&#xff0c;最后总结网络综合面试题&#xff0c;历时六天全文一千字。 其他经典面试题参考程序员…

虹科校园大使招募令

虹科校园大使招募令 我们正式邀请你成为虹科校内明星代言人&#xff01; 近距离接触技术大牛工作领域 来自人力总监的职业发展指导 官方校园大使认证证书 走内部通道提前斩获校招offer 你将成为 校园品牌首席推广师 赋予你自主“DIY”的权利&#xff0c;与校招负责人一起…

损失函数——机器学习

目录 一、实验内容 二、实验过程 1、算法思想 2、算法原理 3、算法分析 三、源程序代码 四、运行结果分析 五、实验总结 一、实验内容 理解损失函数的基本概念&#xff1b;理解并掌握均方差损失函数的原理&#xff0c;算法实现及代码测试分析&#xff1b;理解并掌握交叉…

【linux】linux实操篇之权限管理

14天学习训练营导师课程&#xff1a; 互联网老辛《 符合学习规律的超详细linux实战快速入门》 目录前言权限的基本介绍rwx权限详解更改文件属性1、chgrp&#xff1a;更改文件属组2、chown&#xff1a;更改文件属主&#xff0c;也可以同时更改文件属组3、chmod&#xff1a;更改文…

帷幄前沿茶话丨如何发起一场直播间运营变革?

打开抖音&#xff0c;各种各样的带货模式都有。吃播的、喊麦的、跳舞的、说相声的&#xff0c;各种表现形式都可以是带货的手段。 但实际效果如何复盘&#xff1f;一旦感性的带货模式回归到理性分析&#xff0c;问题就没那么简单了。 电商的关键衡量指标是 GMV。直播带货中&…

[附源码]java毕业设计学院竞赛管理信息系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

RabbitMQ【基本使用】

目录 消息队列 1. Message queue 释义 1.1 问题思考 ? 1.2 存在问题 1.3 优化方案 1.4 案例分析 1.5 带来的好处 1.6 消息队列特点 1.7 Email邮件案例分析 2. 消息队列相关 2.1 AMQP 3. Docker安装部署RabbitMQ 4. springboot连接配置 4.1 RabbitMQ 配置账号…

Unity记录

第四课&#xff1a;组件 自定义组件&#xff0c;主要是 编写 脚本 脚本&#xff1a;要求必须 挂载 到游戏物体上&#xff0c;才能使用 主要组件&#xff1a; &#xff08;1&#xff09;gameObject 游戏对象 VS中的显示 总结&#xff1a; //属性 name:名称 tag : 标签名称 ac…

Execution failed for task ‘:app:javaPreCompileDebug‘.

debug运行app到模拟器的时候&#xff0c;一直报错&#xff0c;然后百度了下&#xff0c;给出的答案是&#xff1a; android { defaultConfig { //添加如下配置就OK了 javaCompileOptions { annotationProcessorOptions { includeCompileClasspath true } } } 但是加了之后&am…