MySQL面经

打印 上一主题 下一主题

主题 984|帖子 984|积分 2952

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
内容援引自JavaGuide、哔哩哔哩黑马程序员数据库从入门到精通,感谢各位大神原创分享
数据库Mysql

常见的关系型数据库包括mysql、SQL Server、Oracle、常见的非关系型数据库Redis、MongDB等。
特点
Mysql开源免费,生态完善,支持事务、高可用(读写分离、分库分表)。
基础架构:


  • 服务层:连接器、查询缓存(移除)、分析器、优化器、执行器;通用日志模块binlog
  • 存储引擎层:插件式存储引擎(为表设置存储引擎),支持InnoDB、MyISAM等;InnoDB包括redolog和undolog日志
存储引擎

使用插件式存储引擎,默认InnoDB支持事务、行锁、外键,数据恢复(redolog),MyISAM不支持事务、采用表锁、不支持外键,不支持数据恢复。此外InnoDB主键使用聚簇索引,叶子节点保存记录,MyISAM使用非聚簇索引,叶子节点保存记录的地址,两者均为B+ Tree。
MySQL索引

用于快速查询或快速定位的排序的数据结构,常见的索引结构包括Hash树、B树、B+树、红黑树。InnoDB和MyISAM均使用B+树作为索引结构。
索引优缺点
优点:加快检索速度,创建唯一索引保证数据唯一性。缺点:创建、维护索引时间开销,且索引占物理存储空间。
索引结构


  • 为什么不使用hash?
    可能出现哈希碰撞(拉链式)、不支持顺序查找和范围查找。
  • 为什么不使用B树?
    B树节点存索引和数据,B+树只有叶子节点存储索引和数据且构成双向链表,其它节点存储索引,故相同数据量下B树高度更高,查询效率更低,且不支持范围查找。
  • 为什么不使用红黑树?
    红黑树是自平衡二叉查找树,树过高造成大量的磁盘 IO。
  • B+树一般不超过3层,能存储多少数据?
    最小存储单元一页16KB,叶子节点存索引和记录,假设索引和一条记录占1KB,则一页可存16K/1K=16条记录,非叶子节点存索引和指针,假设主键索引为bigint占8字节,指针占6字节,则一个节点可存16k/(8+4)=1170 个指针,两层的B+树可存1170*16条记录,三层的B+树可存1170*1170*16条记录,约两千万数据量。
索引的类别
​                索引相关的概念包括聚簇索引、非聚簇索引、主键索引、辅助索引、唯一索引、普通索引、联合索引、覆盖索引、前缀索引、全文索引。
​                聚簇索引,叶子节点保存索引和记录,非聚簇索引叶子节点保存索引和记录相关值(记录地址或主键),且InnoDB存储引擎非聚簇索引不一定需要回表查询(覆盖索引)
​                主键索引,非null,不可重复,没有显示指定时检查是否存在非null的唯一索引,存在则将该字段作为主键索引否则默认创建6字节的自增索引。设计表时不建议使用过长字段作为主键,不建议使用非单调字段作为主键(引发索引频繁分裂,这解释了为什么不宜使用UUID作为主键)。
​                联合索引,多个字段一起创建索引,索引使用要求满足最左匹配原则,缺失停止匹配,范围查询右侧字段停止匹配
  1. # 创建(a,b,c)联合索引 等值查询中a、ab、abc均可使用索引,b、bc、c不可使用索引,全部为等值查询时字段顺序对是否使用索引不产生影响;
  2. # 以下语句a,b走索引,c不走索引,建议将区分度高的字段放最左侧以过滤更多数据
  3. select * from t where a=1 and b > 1 and c=1;  
  4. # 如果是建立(a,c,b)联合索引,则a,b,c都走索引
复制代码
​                索引下推:非聚簇索引遍历过程中,根据索引中包含的字段过滤不符合条件的记录,减少回表次数。
正确使用索引


  • 是否有必要创建索引,很少查询的表没必要创建索引,频繁更新的字段不适合创建索引;
  • 为哪些字段创建索引,为查询字段,排序字段和分组字段创建索引,优先创建联合索引且区分度高的字段放在左侧(可能产生覆盖索引效果,避免回表,且可以过滤较多记录),字符串类型的字段可优先考虑前缀索引;
  • 避免索引失效,如隐式类型转换、在字段上进行函数操作、or逻辑中某条件字段没有索引则涉及的索引全部失效
索引优化


  • SQL提示,在SQL语句中加入人为提示优化操作use index、ignore index、force index,注意use index仅是建议,不代表优化器会选择的执行计划;
  • 插入数据,批量插入、手动提交事务、主键顺序插入
  • 主键 优化,减少主键长度、主键递增、避免对主键进行修改
  • update优化,InnoDB行锁针对索引,有索引时锁行,没有索引锁表
  1. #id有主键索引,锁行;
  2. update student set no = '123' where id = 1;
  3. #name没有索引,锁表
  4. update student set no = '123' where name = 'test';
复制代码

  • order by优化,多字段排序且一个升序一个降序,要注意创建索引时索引的升序和降序
  • limit优化,覆盖索引、子查询、联表查询
  1. # 优化前
  2. SELECT * FROM xxx limit 1000000,20
  3. # 子查询优化
  4. SELECT * FROM xxx WHERE ID >=(select id from xxx limit 1000000, 1) limit 20;
  5. # 联表优化
  6. SELECT * FROM xxx a JOIN (select id from xxx limit 1000000, 20) b ON a.ID = b.id;
复制代码
MySQL事务

ACID原则,原子性、一致性、隔离性、持久性
​                其中一致性是目的,原子性是指要么都执行,要么都不执行,隔离性是指并发事务的独立性,持久性是指事务被提交后可持久化。
并发事务的问题,脏读、不可重复读、幻读
​                脏读是指事务A读取事务B未提交的数据,不可重复读是指事务A多次读某条记录的读取结果不同,幻读是指幻读指事务A读取某一范围的数据行,事务B在该范围内插入了新行,事务A再读取该范围的数据行时,出现幻影行。
并发事务控制,锁+MVCC
​                MySQL中通过读写锁实现并发控制,读锁为共享锁,写锁为排它锁,读读兼容,读写或写写互斥。按粒度MySQL锁又可划分为表锁和行锁,其中表锁不会出现死锁,锁冲突概率高,并发性能低;行锁针对索引字段加锁,会出现死锁,并发度高,行锁 又包括记录锁、间隙锁、临键锁。

  • 行锁发生死锁的场景描述
事务A事务B1、delete from xxxx where id = 1;2、delete from xxxx where id = 2;3、delete from xxxx where id = 2;
事务A等事务B释放记录2行锁4、delete from xxxx where id = 1;
事务B等事务A释放记录1行锁

  • MVCC 多版本并发控制
​                MySQL的隔离级别包括读未提交(脏读、不可重复读、幻读风险),读已提交(不可重复读,幻读风险),可重复读(默认隔离级别,幻读风险)和可串行化。特殊的,InnoDB实现的可重复读隔离级别可解决幻读风险,快照读由MVCC机制保证,当前读使用临键锁保证。
​                在读已提交和可重复读隔离级别下,执行普通select会使用一致性非锁定读MVCC,读记录的快照数据;执行insert、delete、update、select...lock in share mode、select...for update会使用锁定读,读取记录的最新数据,并对读取到的记录加锁,即当前读。
​                MVCC机制的实现依赖隐藏字段、Read View和undo log,InnoDB存储引擎为记录添加默认主键(主键不存在且不存在非空的唯一索引时默认添加)、事务id,回滚指针3个隐藏字段;读已提交隔离级别下每次select查询前创建Read View,可重复读隔离级别下事务开始第一次select前创建Read View,Read View用于可见性判断,主要包括m_low_limit_id、m_up_limit_id、m_ids、m_creator_trx_id字段,根据数据可见性算法(比较记录的事务id和Read View中字段)若当前记录对该事务不可见则使用回滚指针进行数据回滚。
三大日志

​                Mysql日志包括查询日志、慢查询日志、错误日志和binlog日志、redolog日志、undolog日志,其中binlog支持数据备份和主从同步,rodolog支持数据 恢复以保证持久性,undolog支持事务回滚以保证原子性和支持MVCC多版本并发控制。
binlog - MySQL
​                binlog日志支持数据备份和主从同步,包括三种记录格式statement、row和mixed,其中statement记录SQL语句(获得时间戳等SQL语句容易导致数据备份不一致或主从数据不一致),row记录SQL语句和操作数以规避以上问题,但占用内存,折中方案mixed由MySQL判断是否会引起数据不一致,选择statement或row。
​                binlog的刷盘策略:1)事务提交将binlog cache写入到page cache,系统自行决定刷盘;2)事务提交进行刷盘;3)折中方案,提交事务binlog cache写入到page cache,提交N个事务进行刷盘;
redolog - InnoDB
​                redolog日志支持数据恢复,保证事务的持久性。Mysql数据以页16KB为单位(页、段、区、表),查询记录时从磁盘加载数据页放入缓冲池Buffer pool中,后续查询优先在缓冲池中查找,未命中再从磁盘加载,减少IO开销。更新记录时,更新缓存数据,将数据页上的更新记录到redolog buffer中,根据一定的刷盘策略进行持久化。
​                rodolog刷盘策略:1)事务提交不进行刷盘(Mysql实例挂或宕机可能会有一秒数据的丢失);2)事务提交将redolog buffer写入page cache中(Mysql实例挂没有数据丢失,宕机可能会有一秒的数据丢失);3)事务提交刷盘(Mysql实例挂或宕机不会有数据丢失)。兜底措施后台线程每隔1s将redolog buffer写入到page cache,然后进行刷盘;redolog buffer占用内存到一定阈值后台线程主动刷盘。
​                为什么要使用redolog,而不是直接将修改的数据页刷盘?通常数据更新只影响数据页中的少量记录,且数据页刷盘是随机写,刷盘成本高。采用redolog记录更新属于顺序写,刷盘成本低,有利于提高数据库的并发能力。
​                两阶段提交:redolog prepare - binlog - redolog commit。

  • redolog-宕机-binlog,主从结构中,主使用redolog数据恢复,从使用binlog数据恢复,主从数据不一致。
  • binlog-宕机-redolog,主从结构中主使用redolog,从使用binlog,主从数据不一致。
  • 两阶段提交,redolog prepare - 宕机 - binlog - redolog commit,redolog有事务记录,binlog没有事务记录,事务回滚;redolog prepare -  binlog - 宕机 - redolog commit,redolog有事务记录,binlog也有对应的事务记录,提交事务恢复 数据。
undolog
​        undolog日志支持事务回滚和MVCC,保证事务的原子性和隔离性。
MySQL执行计划

explain sql

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

耶耶耶耶耶

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表