面试题三:MySQL
阅读原文时间:2023年07月08日阅读:1
  1. MySQL有哪些存储引擎?

    MyISAM、InnoDB、CSV、Memory等

    MyISAM和InnoDB比较:

    InnoDB

    MyISAM

    事务

    支持

    不支持

    存储限制

    64TB

    锁粒度

    行锁

    表锁

    崩溃后的恢复

    支持

    不支持

    外键

    支持

    不支持

    全文检索

    5.7后支持

    支持

    InnoDB是默认的存储引擎,也是主流的选择,原因:

  2. 为什么select count(*) from table在MyISAM上比InnoDB上快?

    在不带有where条件的情况下,确实是MyISAM上比InnoDB上快,原因是InnoDB需要实时查询,但是MyISAM是存储引擎内部带有的计数器,因此比较快;

    在带有where条件的情况下,这个结论就不成立了。

  3. count(*)count(column)有什么区别?

    count()函数既可以统计某个列值的数量,也可以统计行数。

    在统计列值的时候,要求列值非NULL,也就是count(column)统计的是某一列的非空的值的结果数;

    count(*)会直接忽略所有的列,直接统计所有的行数,统计结果集的行数时,直接写count(*)意义明确且性能也较好。

  4. 什么是索引?

    MySQL中存储引擎使用类似书籍目录的方式查询数据,先去索引中查找对应的值,然后根据匹配的索引找到对应的数据行。

  5. 索引有什么好处?

  6. 索引有什么坏处?

  7. 索引的使用场景?

  8. 索引的类型?

  9. MySQL索引的创建原则?

  10. MySQL索引的使用注意事项?

  11. MySQL索引的原理?

    12-21题

  12. MySQL有哪些索引的方法?

    B-Tree索引:常用de索引类型

    Hash索引

    • 哈希索引只能用于=!=IN查询,不能用于范围查询;
    • 哈希索引被用来避免数据的排序操作;
    • 哈希索引不能用来部分索引键查询;
    • 哈希索引在任何时候都不能避免权标扫描;
    • 哈希冲突时使用哈希索引性能未必有B-Tree高。
  13. 磁盘相关知识?

    • 系统从磁盘读取数据到内存时是以磁盘块(block)为基本单位的,位于同一个磁盘块中的数据会被一次性读取出来,而不是需要什么取什么。
    • InnoDB存储引擎中有页(Page)的概念,页是其磁盘管理的最小单位。InnoDB 存储引擎中默认每个页的大小为 16 KB,可通过参数 innodb_page_size 将页的大小设置为 4K、8K、16K;
    • 而系统一个磁盘块的存储空间往往没有这么大,因此 InnoDB 每次申请磁盘空间时都会是若干地址连续磁盘块来达到页的大小 16KB 。InnoDB 在把磁盘数据读入到磁盘时会以页为基本单位,在查询数据时如果一个页中的每条数据都能有助于定位数据记录的位置,这将会减少磁盘 I/O 次数,提高查询效率。
  14. 什么是B-Tree索引?

    B-Tree 是为磁盘等外存储设备设计的一种平衡查找树。

  15. 什么是B+Tree索引?

    B+Tree 是在 B-Tree 基础上的一种优化,使其更适合实现外存储索引结构,InnoDB存储引擎就是用 B+Tree 实现其索引结构。

    B-Tree中,每个节点不仅包含key还包含data,而每一页的存储空间是有限的,如果data值较大时就会导致每个节点(一个页)能存储的key的数量减少,当存储的数据量很大时同样会导致B+Tree的深度增加,增加查询时的I/o次数,进而影响整个查询效率。

    因此在B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点只存储key值信息,这样可以大大加大每个节点存储key值数量,降低B+Tree的深度。

  16. B-Tree和B+Tree的不同点?

  17. B-Tree 有哪些索引类型?

  18. 聚簇索引的注意点有哪些?

    InnoDB中的索引被称为聚簇索引,最大限度的提高了I/O密集型应用的性能,但是也存在着几点限制:

  19. 什么是索引的最左匹配特性?

    当B+Tree的数据结构是复合数据结构时,比如索引(name, age, sex),B+Tree是按照从左到右的顺序来搜索的。

    • 比如当 (张三, 20, F) 这样的数据来检索的时候,B+Tree 会优先比较 name 来确定下一步的所搜方向,如果 name 相同再依次比较 age 和 sex ,最后得到检索的数据;
    • 但当 (20, F) 这样的没有 name 的数据来的时候,B+Tree 就不知道下一步该查哪个节点,因为建立搜索树的时候 name 就是第一个比较因子,必须要先根据 name 来搜索才能知道下一步去哪里查询。
    • 比如当 (张三, F) 这样的数据来检索时,B+Tree 可以用 name 来指定搜索方向,但下一个字段 age 的缺失,所以只能把名字等于张三的数据都找到,然后再匹配性别是 F 的数据了。

    sql语句在编写时,字段的顺序无所谓,MySQL会进行优化,只需要满足符合索引的字段即可,如下所示也是可以支持索引的:

    select * from tableName where age = 20 and name = '张三' and sex = '男'
  20. MyISAM索引的实现?

    MyISAM索引使用B+Tree实现,但是需要注意的是MyISAM的数据文件和索引文件是拆分开的,索引文件仅保存数据记录的地址。

  21. MyISAM索引和InnoDB索引的区别?

    相同点:

    • 都是基于B+Tree实现的

    不同点:

    • InnoDB是聚簇索引,MyISAM是非聚簇索引;

    • InnoDB的主键索引,叶子节点存储的直接就是行数据,查询效率很高;

    • MyISAM索引的叶子节点存储的是行数据地址,因此需要再寻址一次才能查询到数据;

    • InnoDB非主键索引的叶子节点存储的是主键和其他带索引的列数据,因此查询时做到覆盖索引会非常高效;

      覆盖索引,指的是基于非主键索引查询,但是查询字段只有主键 ID ,那么在二级索引中就可以查找到

  22. MySQL的四种事务隔离级别?

参考25题

  1. 事务的四种特性?

    原子性(A):一个事务中的所有操作,要么全部成功,要么全部不成功,不会存在中间状态;事务在执行过程中出现错误,那么会恢复到发生事务之前的状态,就像这个事务从来没有发生过一样,也即事务不可分割,不可约简

    一致性(C):事务开始之前和事务结束之后,数据库的完整性没有被破坏。

    隔离性(I): 数据库允许多个并发事务同时对数据读读取和修改的能力,隔离性能够防止多个事务并发执行时由于交叉执行而导致的数据不一致问题。

    事务的隔离级别分为四种:

    • 读未提交
    • 读提交
    • 可重复读
    • 串行化

    持久性(D):事务结束以后,对数据修改就是永久性的不可修改,即使系统故障也不会丢失。

  2. 事务的并发问题?

  3. MySQL的事务隔离级别会产生的并发问题?

    事务的隔离级别越高,数据库的并发性就越差,隔离级别由低到高如下,MySQL的默认隔离级别是可重复读

  4. MySQL的锁机制?

    • 共享锁(读锁):不堵塞,多个用户可以同时读取一个资源,互不干扰;
    • 排它锁(写锁):排它锁会阻塞其他的读锁和写锁,这样只允许一个用户进行写入,防止其他用户读取正在写入的数据。
  5. 锁的粒度?

    • 表锁:系统开销最小,会锁定整张表,MyISAM使用的就是表锁;
    • 行锁:最大程度的支持并发处理,但是也带来了最大的锁开销,InnoDB使用行锁。
  6. 什么是悲观锁?什么是乐观锁?

    • 悲观锁

      悲观锁是指对数据被外界修改持保守态度,因此在整个数据处理过程中,将数据处于锁定状态;

      悲观锁的实现需要依靠数据库提供的锁机制,例如共享锁和排他锁都是悲观锁。

      在悲观锁的情况下,为了保证事务的隔离性,就需要一致性锁定读。读取数据时加锁,其他事务无法修改这些数据,修改删除数据时也要加锁,其他事务无法读取这些数据。

      悲观锁导致数据性能降低,特别是长事务的时候。

    • 乐观锁

      乐观锁实际就死基于版本号,通过CAS实现原子性更新。

  7. 什么是死锁?死锁发生的条件?如何降低死锁发生的概率?

    死锁是多个进程访问同一个数据库时,其中每个进程拥有的锁都是其他进程所需要的,由此造成每个进程都无法继续下去。

    死锁发生的条件:

    1. 互斥性:一个资源同一时间只能被一个进程持有;
    2. 请求和保持条件:一个进程持有一个资源不放,但是又要请求其他进程持有的资源;
    3. 不剥夺条件:进程已经持有的资源,除非自己释放,不然在使用完成之前不能被剥夺;
    4. 环路等待条件:p1等待p2的资源,p2等待p3的资源,p3等待p1的资源;

    如何降低死锁发生概率:

  8. MySQL 中 InnoDB 引擎的行锁是通过加在什么上完成(或称实现)的?为什么是这样子的??

    InnoDB 是基于索引来完成行锁。

    SELECT * FROM tab_with_index WHERE id = 1 FOR UPDATE

    FOR UPDATE可以根据条件来完成行锁锁定,并且 id 是有索引键的列,如果 id 不是索引键那么 InnoDB 将完成表锁,并发将无从谈起。

  9. MySQL 查询执行顺序?

    (7)     SELECT
    (8)     DISTINCT <select_list>
    (1)     FROM <left_table>
    (3)     <join_type> JOIN <right_table>
    (2)     ON <join_condition>
    (4)     WHERE <where_condition>
    (5)     GROUP BY <group_by_list>
    (6)     HAVING <having_condition>
    (9)     ORDER BY <order_by_condition>
    (10)    LIMIT <limit_number>
  10. 聊聊 MySQL SQL 优化?

    数据库设计:尽量把数据库设计的占用磁盘空间更小

    1. 尽可能使用更小的数据类型;

    2. 尽可能定义字段为not null,除非这个字段必须为null

    3. 如果没有用到边长字段,那么就采用固定大小的字段格式;

    4. 表的主索引应该尽可能的短;

    5. 只创建确实需要的索引;

    系统的使用:

  11. MySQL 数据库 CPU 飙升到 500% 的话,怎么处理?

  12. 在 MySQL 服务器运行缓慢的情况下输入什么命令能缓解服务器压力?

  13. 什么是MVCC?

    多版本并发控制(MVCC),是一种用来解决读-写冲突的无锁并发控制,也就是为事务分配单向增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照。 这样在读操作不用阻塞写操作,写操作不用阻塞读操作的同时,避免了脏读和不可重复读.