Mysql面试题分享
1.索引的优点和缺点
索引是mysql中可以高效的从磁盘中去检索数据的一种数据结构,在Mysql的innoDB引擎里面,采用的是B+树的结构去实现索引.
优点:
1.通过B+树存储数据,可以大大减少数据检索时的磁盘IO次数,从而提升数据查询的性能
2.B+树索引在进行范围查找时,只需要找到起始节点,然后基于叶子节点的链表结构往下读取即可,查询效率较高
3.通过唯一索引约束,可以保证数据表中每一行数据的唯一性
缺点:
1.数据在做增加,修改,删除,需要涉及到的索引维护,当数据量较大的情况下,索引的维护会带来较大的性能开销
2.一个表中允许存在一个聚簇索引和多个非聚簇索引,但是索引数不能创建太多,否则造成的索引维护成本过高
3.创建索引的时候,需要考虑到索引字段值的分散性,如果字段的重复数据过多,创建索引反而会带来性能降低
2.为什么mysql使用B+树,而不用B树
B树特点:
1.节点排序
2.一个节点可以存多个元素,多个元素也排序了
B+树的特点:
1.拥有B树的特点
2.叶子节点之间有指针
3.非叶子节点上的元素在叶子节点上都冗余了,也就是叶子节点中存储了所有的元素,并且排好了顺序
1.大部分数据库都是范围查找,B+树的叶子节点是有序链表,直接遍历就行,而B树的范围查找可能两个节点距离很远,只能通过中序遍历去查找,所有使用B+树更合适
2.因为B+树非叶子节点不会存放数据,只有索引值,所以非叶子节点可以保存更多的索引值,这样B+树可以更矮,减少IO次数
3.B树只适合随机检索,而B+树同时支持随机检索和顺序检索(因为叶子节点相当于链表,保存索引值都是有序的)。
顺序检索: 按照序列顺序遍历比较找到给定值。
随机检索: 不断从序列中随机抽取数据进行比较,最终找到结果。
3.最左匹配原则
最左优先,以最左边为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between and、like)就会停止匹配。
例如:Z表建立联合索引 (a,b,c)
//这样索引abc列都起效,因为符合最左匹配原则,where子句几个搜索条件顺序调换不影响查询结果,因为Mysql中有查询优化器,会自动优化查询顺序
select * from Z where a = 1 and b = 2 and c = 3 //因为a列是起点,没有a列匹配不上,所以索引失效
select * from table_name where b = 2 and c = 3 //因为连续不到b,所以只有a列索引生效
select * from table_name where a = 1 and c = 3
4.索引失效的场景
1.不满足最左匹配原则
2.使用了select*
3.索引列上有计算4.索引列上有函数
5.字符串类型的字段,传入了int类型的参数时
6.like左边包含%
7.两个单独建了索引的列,用来做列对比时
8.使用
or
关键字(前面和后面的字段都要加索引)9.使用not in或者not exists
10.使用order by时没加where或limit,不遵守最左匹配,不同排序
5.优化慢查询
1.检查是否走了索引,如果没有就优化sql利用索引
2.检查所利用的索引,是否是最优索引
3.检查所查字段是否都是必须的,是否查询了过多的字段,查出了多余数据
4.检查表中数据是否过多,是否应该进行分库分表
5.检查数据库实例所在的机器的性能配置,是否太低,是否可以适当增加资源
6.分库分表
将原本存储于单个数据库上的数据拆分到多个数据库,把原来存储在单张表的数据拆分到多张数据表中,实现数据切分,从而提升数据库操作性能,分库分表的实现可以分为两种方式:垂直切分和水平切分.
水平:将数据分散到多张表,涉及分区建
分库:每个表结构一样,数据不一样,没有交集,库多了可以缓解io和cpu压力
分表:每个表结构一样,数据不一样,没有交集,表数量减少可以提高sql执行效率,减钱cpu压力
垂直:将字段拆分为多张表,需要一定的重构
分库:每个库结构,数据都不一样,所有库的并集为全量数据
分表:每个表结构,数据不一样,至少有一列交集,所有表的并集为全量数据
7.mysql的长事务问题
MySQL中的长事务通常指执行时间较长的事务,这类事务可能对数据库性能和并发处理带来一系列问题。事务是一组作为单个逻辑工作单元执行的操作,具有ACID特性(原子性、一致性、隔离性、持久性),然而,长事务可能引发锁竞争、资源占用过高、事务日志膨胀等问题。
长事务可能导致的问题
锁竞争与阻塞
事务日志膨胀
一致性与隔离性问题
回滚开销大
长事务问题的解决方案
优化SQL语句与事务逻辑
合理设置事务隔离级别
使用乐观锁机制
定期提交事务
监控与调优
使用读写分离与分库分表
设置合理的超时时间
8.Mysql中innodb引擎执行一条insert语句,中间的日志执行顺序是怎么样的
生成 undo log:系统首先生成一条 undo log 记录,用于记录
DELETE FROM users WHERE id = 1
,以便在事务回滚时使用。修改缓冲池中的数据页:将
INSERT
操作的数据写入缓冲池中的数据页。生成 redo log:生成 redo log 条目,记录该数据页的修改内容。
写入 binlog:事务提交时,binlog 被写入磁盘,记录
INSERT
操作的 SQL 语句。提交事务:事务提交时,redo log 被刷新到磁盘,确保事务的持久性。
9.单体系统中 订单业务,有三张表,订单表,优惠表,明细表 如何保证数据的一致性
使用数据库事务(Transaction):
数据库事务是保证多个操作之间数据一致性的核心机制。通过将涉及订单表、优惠表和明细表的操作包裹在一个事务中,可以确保这些操作要么全部成功,要么全部失败,从而避免部分数据更新导致的不一致问题。
例如,在创建订单时,需要同时插入订单主表数据、优惠信息以及订单明细。如果其中任何一个步骤失败,整个事务将被回滚,确保数据的一致性。采用外键约束(Foreign Key Constraints):
在数据库设计中,通过设置外键约束可以确保订单表、优惠表和明细表之间的关联关系不会被破坏。例如,order_details
表中的order_id
字段应设置为orders
表的外键,确保只有存在的订单才能添加明细记录。使用乐观锁或悲观锁机制:
在高并发场景下,多个用户可能同时修改同一订单数据,导致数据冲突。通过乐观锁(如版本号机制)或悲观锁(如行级锁)可以有效避免此类问题。例如,在更新订单状态时,检查版本号是否匹配,若不匹配则拒绝更新并提示冲突。数据冗余与反范式设计:
在某些场景下,为了提高查询效率,可以适当进行反范式设计,将部分常用字段冗余存储。例如,在订单明细表中冗余存储商品名称和价格,避免频繁关联查询商品表。但需要注意,这种设计会增加数据维护的复杂性,必须确保冗余字段的更新一致性2。定期数据校验与补偿机制:
即使有事务和锁机制,系统仍可能因网络故障、程序错误等原因导致数据不一致。因此,可以设计定期的数据校验任务,检测订单表、优惠表和明细表之间的数据是否一致,并通过补偿机制(如异步修复)进行修正。日志记录与审计:
所有对订单数据的修改操作都应记录到日志表中,包括操作时间、操作人、修改前后的数据等。这不仅有助于排查数据不一致的问题,还能提供审计功能,确保数据变更的可追溯性。
10.mysql基础操作命令
MySQL 是否处于运行状态:
Debian 上运行命令 service mysql status,
在RedHat 上运行命令 service mysqld status
开启或停止 MySQL 服务
service mysqld start 开启服务
service mysqld stop 停止服务
列出所有数据库:运行命令 show databases;
切换到某个数据库并在上面工作:运行命令 use databasename; 进入名为 databasename 的数据库
列出某个数据库内所有表: show tables;
11.一张表,里面有ID自增主键,当insert了17条记录之后,删除了第15,16,17条记录,再把Mysql重启,再insert一条记录,这条记录的ID是18还是15
如果表的类型为MyISAM,ID为18
因为MyISAM表会把自增主键的最大ID记录到数据文件里,重启MySQL自增主键的最大ID也不会丢失
如果表的类型是InnoDB,ID是15
InnoDB表只是把自增主键的最大ID记录到内存中,所以重启数据库或者是对表进行OPTIMIZE操作,都会导致最大ID丢失
12.mysql的主从同步
MySQL 主从同步的工作机制和实现原理
MySQL 主从同步是一种基于二进制日志(Binary Log)的数据复制机制,它通过将主服务器(Master)上的数据变更操作同步到一个或多个从服务器(Slave)上,实现数据的高可用、读写分离和数据备份等功能。这种机制的核心在于主服务器记录所有对数据的更改操作,然后将这些操作传递到从服务器,并在从服务器上重新执行这些操作,从而实现主从数据的一致性。
二进制日志与中继日志的协同作用
在主从同步过程中,主服务器的写操作会被记录到二进制日志中。从服务器通过两个线程协作完成数据同步:I/O线程和SQL线程。I/O线程负责从主服务器读取二进制日志的内容,并将其写入本地的中继日志(Relay Log)中。SQL线程则负责读取中继日志中的内容,并在从服务器上重放这些操作,以确保从服务器的数据状态与主服务器保持一致。这种机制确保了主服务器的写操作能够准确无误地传递到从服务器并得到执行,是实现数据一致性的关键环节。
同步模式的选择
MySQL 主从同步支持多种复制模式,包括基于语句的复制(Statement-Based Replication,SBR)、基于行的复制(Row-Based Replication,RBR)和混合模式(Mixed)。其中,SBR模式通过复制SQL语句来实现数据同步,适用于大多数操作,但在某些情况下可能导致主从数据不一致;而RBR模式则通过复制行的更改来实现同步,更加精确,但会占用更多的网络带宽和存储资源。根据实际业务需求和性能要求,可以选择合适的复制模式以优化同步效果。