MySQL面试题及答案 【最新版】MySQL面试题大全,发现网上很多MySQL面试题及答案整理都没有答案,所以花了很长时间搜集,本套MySQL面试题大全
如果不背 MySQL面试题的答案,肯定面试会挂!
NOW()命令用于显示当前年份,月份,日期,小时,分钟和秒。
CURRENT_DATE()仅显示当前年份,月份和日期。
1.CHAR和VARCHAR类型在存储和检索方面有所不同
2.CHAR列长度固定为创建表时声明的长度,长度值范围是1到255
当CHAR值被存储时,它们被用空格填充到特定长度,检索CHAR值时需删除尾随空格。
**1、**主键是一种约束,唯一索引是一种索引,两者在本质上是不同的。
**2、**主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键。
**3、**唯一性索引列允许空值,而主键列不允许为空值。
**4、**主键列在创建时,已经默认为空值 ++ 唯一索引了。
**5、**一个表最多只能创建一个主键,但可以创建多个唯一索引。
**6、**主键更适合那些不容易更改的唯一标识,如自动递增列、身份证号等。
**7、**主键可以被其他表引用为外键,而唯一索引不能。 ?
共有5种类型的表格:
**1、**MyISAM
**2、**Heap
**3、**Merge
**4、**INNODB
**5、**ISAM
**1、**应用服务器与数据库服务器建立一个连接
**2、**数据库进程拿到请求sql
**3、**解析并生成执行计划,执行
**4、**读取数据到内存并进行逻辑处理
**5、**通过步骤一的连接,发送结果到客户端
**6、**关掉连接,释放资源
索引是通过以下方式为表格定义的:
SHOW INDEX FROM
**1、**B树只适合随机检索,而B+树同时支持随机检索和顺序检索;
**2、**B+树空间利用率更高,可减少I/O次数,磁盘读写代价更低。一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘I/O消耗。B+树的内部结点并没有指向关键字具体信息的指针,只是作为索引使用,其内部结点比B树小,盘块能容纳的结点中关键字数量更多,一次性读入内存中可以查找的关键字也就越多,相对的,IO读写次数也就降低了。而IO读写次数是影响索引检索效率的最大因素;
**3、**B+树的查询效率更加稳定。B树搜索有可能会在非叶子结点结束,越靠近根节点的记录查找时间越短,只要找到关键字即可确定记录的存在,其性能等价于在关键字全集内做一次二分查找。而在B+树中,顺序检索比较明显,随机检索时,任何关键字的查找都必须走一条从根节点到叶节点的路,所有关键字的查找路径长度相同,导致每一个关键字的查询效率相当。
**4、**B-树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。B+树的叶子节点使用指针顺序连接在一起,只要遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作。
**5、**增删文件(节点)时,效率更高。因为B+树的叶子节点包含所有关键字,并以有序的链表结构存储,这样可很好提高增删效率。
第一范式:每个列都不可以再拆分。
第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分。
第三范式:在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非主键。
在设计数据库结构的时候,要尽量遵守三范式,如果不遵守,必须有足够的理由。比如性能。事实上我们经常会为了性能而妥协数据库的设计。
**1、**对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引
**2、**用索引可以提高查询
**3、**SELECT子句中避免使用*号,尽量全部大写SQL
**4、**应尽量避免在 where 子句中对字段进行 is null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,使用 IS NOT NULL
**5、**where 子句中使用 or 来连接条件,也会导致引擎放弃使用索引而进行全表扫描
**6、**in 和 not in 也要慎用,否则会导致全表扫描
**1、**覆盖索引: 查询列要被所建的索引覆盖,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。
**2、**回表:二级索引无法直接查询所有列的数据,所以通过二级索引查询到聚簇索引后,再查询到想要的数据,这种通过二级索引查询出来的过程,就叫做回表。
排查过程:
**1、**使用top 命令观察,确定是MySQLd导致还是其他原因。
**2、**如果是MySQLd导致的,show processlist,查看session情况,确定是不是有消耗资源的sql在运行。
**3、**找出消耗高的 sql,看看执行计划是否准确, 索引是否缺失,数据量是否太大。
处理:
**1、**kill 掉这些线程(同时观察 cpu 使用率是否下降),
**2、**进行相应的调整(比如说加索引、改 sql、改内存参数)
**3、**重新跑这些 SQL。
其他情况:
也有可能是每个 sql 消耗资源并不多,但是突然之间,有大量的 session 连进来导致 cpu 飙升,这种情况就需要跟应用一起来分析为何连接数会激增,再做出相应的调整,比如说限制连接数等
**1、**Where子句中:where表之间的连接必须写在其他Where条件之前,那些可以过滤掉最大数量记录的条件必须写在Where子句的末尾.HAVING最后。
**2、**用EXISTS替代IN、用NOT EXISTS替代NOT IN。
**3、**避免在索引列上使用计算
**4、**避免在索引列上使用IS NULL和IS NOT NULL
**5、**对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
**6、**应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描
**7、**应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描
有多少种日志
innodb两种日志redo和undo。
日志的存放形式
**1、**redo:在页修改的时候,先写到 redo log buffer 里面, 然后写到 redo log 的文件系统缓存里面(fwrite),然后再同步到磁盘文件( fsync)。
**2、**Undo:在 MySQL5.5 之前, undo 只能存放在 ibdata文件里面, 5.6 之后,可以通过设置 innodb_undo_tablespaces 参数把 undo log 存放在 ibdata之外。
事务是如何通过日志来实现的
**1、**因为事务在修改页时,要先记 undo,在记 undo 之前要记 undo 的 redo, 然后修改数据页,再记数据页修改的 redo。 Redo(里面包括 undo 的修改) 一定要比数据页先持久化到磁盘。
**2、**当事务需要回滚时,因为有 undo,可以把数据页回滚到前镜像的 状态,崩溃恢复时,如果 redo log 中事务没有对应的 commit 记录,那么需要用 undo把该事务的修改回滚到事务开始之前。
**3、**如果有 commit 记录,就用 redo 前滚到该事务完成时并提交掉。
不一定,如果查询语句的字段全部命中了索引,那么就不必再进行回表查询(哈哈,覆盖索引就是这么回事)。
举个简单的例子,假设我们在学生表的上建立了索引,那么当进行select age from student where age < 20的查询时,在索引的叶子节点上,已经包含了age信息,不会再次进行回表查询。