告诉面试官MySQL的逻辑结构。如果你有一块白板,你可以画下图。图片来自网络。Mysql逻辑架构图主要分为三层:(1)第一层负责连接处理、授权认证、安全等(2)第二层负责SQL的编译和优化(3)第三层是存储引擎。MySQL中如何执行SQL查询?首先检查语句是否有权限,如果没有,直接返回错误信息,如果有权限,会先查询缓存(MySQL8.0之前的版本)。如果没有缓存,则分析器进行词法分析,提取出sql语句中的select等关键元素,然后判断sql语句是否存在语法错误,如关键字是否正确等,最后由优化器判断执行计划并进行权限验证。如果没有权限,则直接返回错误信息。如果有权限,就会调用数据库引擎接口,返回执行结果。SQL优化你在日常工作中是如何优化SQL的?这个问题可以从这几个维度来回答:1.优化表结构(1)尽量使用数值型字段。如果只包含数字信息的字段尽量不要设计成字符类型,这样会降低查询和连接的性能,还会增加存储。高架。这是因为引擎在处理查询和连接时,会把字符串中的每个字符一个一个地进行比较,但是对于数字类型,只需要一个比较就可以了。(2)尽量使用varchar,而不是char。变长字段存储空间小,可以节省存储空间。(3)当索引列中有大量重复数据时,可以删除索引。比如有一列性别,几乎只有男、女、未知。这样的索引是无效的。2、优化查询尽量避免在where子句中使用!=或<>操作符。尽量避免在where子句中使用或连接条件。不要在任何查询中使用select*并避免在where子句中使字段为空。值判断3、索引优化为作为查询条件和orderby的字段创建索引,避免创建过多索引,多使用复合索引。怎么看执行计划(explain),理解各个字段的意思?在select语句前加上explain关键字,会返回执行计划信息。(1)id列:是select语句的序号。MySQL将select查询分为简单查询和复杂查询。(2)select_typecolumn:表示对应的行是简单查询还是复杂查询。(3)表列:表示一行explain访问的是哪个表。(4)类型栏:最重要的栏目之一。指示关联类型或访问类型,MySQL决定如何在表中查找行。从最好到最差是:system>const>eq_ref>ref>fulltext>ref_or_null>index_merge>unique_subquery>index_subquery>range>index>ALL(5)possible_keyscolumn:显示查询可能使用哪些索引来查找。(6)key列:该列显示mysql实际使用哪个索引来优化对表的访问。(7)key_len列:显示mysql在索引中使用的字节数。通过这个值可以计算出索引中的哪些列被使用了。(8)refcolumn:该列显示了在索引中记录的keycolumn中的表查找值中使用的列或常量。常见的有:const(常量)、func、NULL、字段名。(9)rows列:这一列是mysql估计读取检测的行数。请注意,这不是结果集中的行数。(10)Extracolumn:显示额外信息。比如有Usingindex、Usingwhere、Usingtemporary等等。你有没有关心过业务系统中那些耗时的SQL?也算慢查询?您如何优化慢速查询?我们平时写Sql的时候,一定要养成使用explain分析的习惯。慢查询统计,运维会定期统计给我们优化慢查询的思路:分析语句,是否加载了不需要的字段/数据分析SQL执行语句,是否命中索引等。如果SQL复杂,优化SQL结构如果表数据考虑聚簇索引和非聚簇索引的区别,分表索引可以根据以下四个维度来回答:(1)一个表中只能有一个聚簇索引,而多个非聚簇索引索引可以存在于表中。(2)聚簇索引,索引中键值的逻辑顺序决定了表中对应行的物理顺序;非聚集索引,索引在索引中的逻辑顺序不同于行在磁盘上的物理存储顺序。(3)索引用二叉树的数据结构来描述。我们可以这样理解聚集索引:索引的叶子节点就是数据节点。非聚集索引的叶子节点仍然是索引节点,只是有一个指针指向对应的数据块。(4)聚簇索引:物理存储按索引排序;非聚集索引:物理存储不按索引排序;为什么要用B+树而不是普通的二叉树?可以从几个维度来看这个问题,查询速度够不够快,效率是否稳定,存多少数据,查盘多少。为什么不是普通二叉树,为什么不是平衡二叉树,为什么不是B树,而是B+树?(1)为什么不是普通的二叉树?如果将二叉树特化为链表,相当于全表扫描。与二叉搜索树相比,平衡二叉树的搜索效率更稳定,整体搜索速度更快。(2)为什么不是平衡二叉树?我们知道在内存中查询效率要比在磁盘数据中快很多。如果使用树数据结构作为索引,那么我们每次查找数据都需要从磁盘中读取一个节点,也就是我们所说的磁盘块,但是平衡二叉树只存储一个键值和每个数据节点。如果是B树,可以存储更多的节点数据,树的高度也会降低,所以读磁盘的次数会减少,查询效率会更快。(3)为什么不是B树而是B+树?B+树的非叶子节点不存储数据,只存储键值,而B-树节点不仅存储键值,还存储数据。innodb中页面的默认大小是16KB。如果不存储数据,存储的key值越多,对应的树(节点的子节点树)的阶数越大,树越矮越胖。这样一来,我们需要为磁盘查找数据的IO次数就会再次减少,数据查询的效率也会更快。B+树索引的所有数据都存放在叶子节点中,数据按顺序排列,链表相连。那么B+树使得范围搜索、排序搜索、分组搜索和去重搜索变得异常简单。Hash索引和B+树索引有什么区别?你是如何选择设计索引的?B+树可以进行范围查询,而Hash索引不行。B+树支持联合索引的最左原则,而Hash索引不支持。B+树支持orderbysorting,而Hashindex不支持。哈希索引在等价查询上比B+树更高效。B+树在使用like进行模糊查询时,like后面的词(如%开头)可以起到优化作用,而Hash索引根本无法进行模糊查询。什么是最左前缀原则?什么是最左匹配原则?最左前缀原则就是最左优先级。在创建多列索引时,根据业务需要,将where子句中使用频率最高的列放在最左边。当我们创建一个复合索引时,比如(a1,a2,a3),相当于创建了三个索引(a1),(a1,a2)和(a1,a2,a3),这就是最左匹配原则。哪些场景不适合使用索引?少量数据不适合索引。频繁更新不适合索引=区分度低的字段不适合索引(比如性别)。索引的优点和缺点是什么?(1)优点:唯一索引可以保证数据库表中每一行数据的唯一性。索引可以加快数据查询速度,减少查询时间(2)缺点:创建和维护索引需要时间。索引需要物理空间,数据除外。除了表占用的数据空间外,每个索引还占用一定的物理空间。当对表中的数据进行增删改查时,索引也必须动态维护。锁定MySQL您是否遇到过死锁问题,您是如何解决的?遇见了。我解决死锁的一般步骤是:(1)检查死锁日志showengineinnodbstatus;(2)找出死锁sql(3)分析sql锁情况(4)模拟死锁事件(5)分析死锁日志(6)分析死锁结果,说说什么是数据库中的乐观锁和悲观锁及其作用差异?(1)悲观锁:悲观锁是专用的,不安全的。她的心只属于当前事务,总是担心自己心爱的数据可能被其他事务修改,所以一个事务拥有(获得)悲观锁后,其他事务都不能修改数据,只能等待执行前要释放的锁。(2)乐观锁:乐观锁的“乐观”体现在它认为数据变化不会太频繁。因此,它允许多个事务同时对数据进行更改。实现方法:乐观锁一般使用版本号机制或者CAS算法来实现。您熟悉MVCC并了解其基本原理吗?MVCC(MultiversionConcurrencyControl),即多版本并发控制技术。MySQLInnoDB中MVCC的实现,主要是为了提高数据库的并发性能,更好的处理读写冲突,这样即使有读写冲突,也能实现非锁和非阻塞并发读取。事务的四大特点MySQL事务及其实现原理原子性:事务作为一个整体执行,包含在其中的对数据库的操作要么全部执行,要么都不执行。一致性:表示在事务开始前和事务结束后数据都不会被破坏。如果A账户向B账户转10元,无论成功与否,A和B的总金额不变。隔离性:当多个事务并发访问时,事务之间是相互隔离的,即一个事务不影响其他事务的运行效果。简而言之,就是事与愿违,水到渠成。持久化:事务完成后,事务对数据库的操作改变会持久保存在数据库中。事务的隔离级别是多少?MySQL的默认隔离级别是多少?未提交读(ReadUncommitted)已提交读(ReadCommitted)可重复读(RepeatableRead)可序列化(Serializable)Mysql默认的事务隔离级别是可重复读(RepeatableRead)。反复阅读呢?事务A和B交替执行,事务A被事务B干扰,因为事务A读取了事务B未提交的数据,属于脏读。在一个事务范围内,两个相同的查询读取相同的记录,但返回不同的数据,是不可重复读。事务A查询一个范围内的结果集,另一个并发事务B向这个范围内插入/删除数据,并悄悄提交,然后事务A再次查询同一个范围,两次读取得到的结果集不一样,这就是幻读.实际MySQL数据库CPU飙升怎么办?排查过程:(1)用top命令观察,判断是mysqld还是其他原因造成的。(2)如果是mysqld引起的,showprocesslist,查看session状态,判断是否有耗资源的SQL在运行。(3)找出高消耗的sql,检查执行计划是否准确,索引是否缺失,数据量是否过大。处理:(1)kill这些线程(同时观察cpu使用率是否下降),(2)做相应的调整(比如加索引,改sql,改内存参数)(3)重新运行这些sql。其他情况:也有可能是每条SQL消耗资源不多,突然,大量session进来导致CPU飙升。这种情况下,就需要分析为什么连接数会随着应用激增,然后做出相应的应对调整,比如限制连接数等MYSQL主从延迟,你是怎么解决的?主从复制分为五个步骤:(图片来自网络)第一步:将主库的更新事件(update、insert、delete)写入binlog第二步:从库向从库发起连接主图书馆。Step3:此时主库创建一个binlogdump线程,将binlog的内容发送给从库。第四步:从库启动后,创建I/O线程从主库读取binlog内容,写入relaylog。第五步:创建一个SQL线程从relaylog中读取内容,从读取内容到Exec_Master_Log_Pos位置开始执行读取更新事件,并将更新内容写入slave的db。主从同步延迟的原因是一个服务器打开了N个链接供客户端连接,所以会有一个大的并发更新操作,但是从服务器读取binlog的线程只有一个。当某条SQL在从服务器上执行时间过长,或者因为某条SQL需要锁表,会导致主服务器上SQL大量积压,一直没有同步到从服务器上。在服务器中。这就导致了主从不一致,也就是主从延迟。主从同步延迟的解决方案主服务器负责更新操作,对安全性要求比从服务器高,所以可以修改一些设置参数,比如sync_binlog=1,innodb_flush_log_at_trx_commit=1等设置。选择一个更好的硬件设备作为slave。使用从服务器作为备份而不是提供查询,减少了那边的负载,那么执行relaylog中的SQL的效率自然会高。增加从服务器的目的是分散读取压力,从而减轻服务器负载。如果让你设计分库分表,简而言之你会怎么做?分库分表方案:水平分库:将一个数据库中的数据按照一定的策略(hash、range等)按字段拆分到多个数据库中。水平分表:将一张表中的数据按字段按照一定的策略(hash、range等)拆分成多张表。垂直分库:以表为基础,根据不同的业务属性,将不同的表拆分成不同的库。垂直分表:以字段为基础,将表中的字段根据字段的活跃度拆分成不同的表(主表和扩展表)。常用的分库分表中间件:sharding-jdbcMycat分库分表可能会遇到的问题事务问题:需要使用分布式事务跨节点Join问题:为了解决这个问题,可以将查询一分为二实现跨-nodeCount,orderby,groupby,aggregationfunctionissues:在每个节点上获取结果后,在应用端合并。数据迁移、容量规划、扩容等ID问题:数据库拆分后,不能再依赖数据库本身的主键生成机制。最容易考虑的就是UUID跨分片排序和分页问题
