1.请你谈谈 MySQL 事务隔离级别,MySQL 的默认隔离级别是什么?
为了达到事务的四大特性,数据库定义了 4 种不同的事务隔离级别:
- READ-UNCOMMITTED(读取未提交):最低的隔离级别,允许脏读,也就是可能读取 到其他会话中未提交事务修改的数据,可能会导致脏读、幻读或不可重复读。
- READ-COMMITTED(读取已提交): 只能读取到已经提交的数据。Oracle 等多数数 据库默认都是该级别 (不重复读),可以阻止脏读,但是幻读或不可重复读仍有可能发 生。
- REPEATABLE-READ(可重复读):对同一字段的多次读取结果都是一致的,除非数据 是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
- SERIALIZABLE(可串行化):最高的隔离级别,完全服从 ACID 的隔离级别。所有的 事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏 读、不可重复读以及幻读。
- MySQL 默认采用的 REPEATABLE_READ 隔离级别。
2、可重复读解决了哪些问题?
- 可重复读的核心就是一致性读(consistent read);保证多次读取同一个数据时,其值都和事 务开始时候的内容是一致,禁止读取到别的事务未提交的数据,会造成幻读。
- 而事务更新数据的时候,只能用当前读。如果当前的记录的行锁被其他事务占用的话,就 需要进入锁等待。
- 查询只承认在事务启动前就已经提交完成的数据。
- 可重复读解决的是重复读的问题,可重复读在快照读的情况下是不会有幻读,但当前读的 时候会有幻读。
3、对 SQL 慢查询会考虑哪些优化 ?
? 分析语句,是否加载了不必要的字段/数据。 ? 分析 SQL 执行计划(expl索引信息。 ? 如果 SQL 很复杂,优化 SQL 结构。 ? 按照可能的优化点执行表结构变更、增加索引、SQL 改写等操作。 ? 查看优化后的执行时间和执行计划。 ? 如果表数据量太大,考虑分表。 ? 利用缓存,减少查询次数
4、MySQL 为什么 InnoDB 是默认引擎?
聚集索引是指数据库表行中数据的物理顺序与键值的逻辑(索引)顺序相同。一个表只能有一 个聚簇索引,因为一个表的物理顺序只有一种情况,所以,对应的聚簇索引只能有一个。聚簇 索引的叶子节点就是数据节点,既存储索引值,又在叶子节点存储行数据。 Innodb 创建表后生成的文件有: frm:创建表的语句 idb:表里面的数据+索引文件
5、MySQL 索引底层结构为什么使用 B+树?
? 哈希虽然能够提供 O(1) 的单数据行操作性能,但是对于范围查询和排序却无法很好地支 持,最终导致全表扫描;B 树能够在非叶节子点中存储数据,但是这也导致在查询连续数 据时可能会带来更多的随机 I/O,而 B+树的所有叶节点可以通过指针相互连接,能够减 少顺序遍历时产生的额外随机 I/O; ? 第一,B 树一个节点里存的是数据,而 B+树存储的是索引(地址),所以 B 树里一个节 点存不了很多个数据,但是 B+树一个节点能存很多索引,B+树叶子节点存所有的数据。 ? 第二,B+树的叶子节点是数据阶段用了一个链表串联起来,便于范围查找。
6、B+ 树的叶子节点链表是单向还是双向?
双向链表
7、如何查询慢 SQL 产生的原因
? 分析 SQL 执行计划(explain extended),思考可能的优化点,是否命中索引等。 ? 没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)。 ? 内存不足。 ? 网络速度慢。 ? 是否查询出的数据量过大(可以采用多次查询,其他的方法降低数据量)。 ? 是否返回了不必要的行和列。 ? 锁或者死锁。 ? I/O 吞吐量小,形成了瓶颈效应。 ? sp_lock,sp_who,活动的用户查看,原因是读写竞争资源。
8、索引失效的情况有哪些?
? like 以%开头索引无效,当 like 以&结尾,索引有效。 ? or 语句前后没有同时使用索引,当且仅当 or 语句查询条件的前后列均为索引时,索引 生效。 ? 组合索引,使用的不是第一列索引时候,索引失效,即最左匹配规则。 ? 数据类型出现隐式转换,如 varchar 不加单引号的时候可能会自动转换为 int 类型,这 个时候索引失效。 ? 在索引列上使用 IS NULL 或者 IS NOT NULL 时候,索引失效,因为索引是不索引空值 得。 ? 在索引字段上使用,NOT、 <>、!= 、时候是不会使用索引的,对于这样的处理只会进 行全表扫描。 ? 对索引字段进行计算操作,函数操作时不会使用索引。 ? 当全表扫描速度比索引速度快的时候不会使用索引。
9、MySQL 事务的特性有什么,说一下分别是什么意思?
? 原子性:即不可分割性,事务要么全部被执行,要么就全部不被执行。 ? 一致性或可串性。事务的执行使得数据库从一种正确状态转换成另一种正确状态。 ? 隔离性。在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事务。 ? 持久性。事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故 障,事务的处理结果也会得到保存。
10、介绍下 MySQL 聚簇索引与非聚簇索引的区别(InnoDB 与 Myisam 引 擎)?
聚集索引是指数据库表行中数据的物理顺序与键值的逻辑(索引)顺序相同。一个表只能有一 个聚簇索引,因为一个表的物理顺序只有一种情况,所以,对应的聚簇索引只能有一个。 聚簇索引的叶子节点就是数据节点,既存储索引值,又在叶子节点存储行数据。 Innodb 创建表后生成的文件有: frm:创建表的语句 idb:表里面的数据+索引文件 非聚集索引(MyISAM 引擎的底层实现)的逻辑顺序与磁盘上行的物理存储顺序不同。 非聚簇索引的叶子节点仍然是索引节点,只不过有指向对应数据块的指针。索引命中后,需要回表查 询。 Myisam 创建表后生成的文件有: frm:创建表的语句 MYD:表里面的数据文件(myisam data) MYI:表里面的索引文件(myisam index) innodb 的次索引指向对主键的引用 (聚簇索引) myisam 的次索引和主索引都指向物理行 (非聚簇索引)
11、然后给一个联合索引(a,b)和一个语句,select * from table where b = ‘xxx’, 判断是否能命中索引?为什么?
不能命中。 对于查询 SELECT * FROM TABLE WHERE a=xxx and b=xxx,显然是可以使用(a,b) 这个联合索引的。 对于单个的 a 列查询 SELECT * FROM TABLEWHERE a=xxx,也可以使用这个(a,b) 索引。 但对于 b 列的查询 SELECT *FROM TABLE WHERE b=xxx,则不可以使用这棵 B+树索 引。在 innoDb 数据引擎中,可以发现叶子节点上的 b 值为 1、2、1、4、1、2,显然不是排序 的,因此对于 b 列的查询使用不到(a,b)的索引
12、MySQL 索引分类?
单列索引 ? 普通索引:MySQL 中基本索引类型,没有什么限制,允许在定义索引的列中插入重复值 和空值,纯粹为了查询数据更快一点。 ? 唯一索引:索引列中的值必须是唯一的,但是允许为空值, ? 主键索引:是一种特殊的唯一索引,不允许有空值。 组合索引: 多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使 用,使用组合索引时遵循最左前缀集合。 全文索引: 只有在 MyISAM 引擎上才能使用,只能CHAR,VARCHAR,TEXT 类型字段上使用全文 索引,介绍了要求,说说什么是全文索引,就是在一堆文字中,通过其中的某个关键字等,就 能找到该字段所属的记录行,比有"你是个靓仔,靓女 …" 通过靓仔,可能就可以找到该条记录 空间索引: 空间索引是对空间数据类型的字段建立的索引,MySQL 中的空间数据类型有四种, GEOMETRY、POINT、LINESTRING、POLYGON。在创建空间索引时,使用 SPATIAL 关 键字。要求,引擎为 MyISAM,创建空间索引的列,必须将其声明为 NOT NULL。
13、谈谈你对 SQL 注入式攻击的理解?
所谓 SQL 注入式攻击,就是攻击者把 SQL 命令插入到 Web 表单的输入域或页面请求的 查询字符串,欺骗服务器执行恶意的 SQL 命令。 如何防范 SQL 注入式攻击? 在利用表单输入的内容构造 SQL 命令之前,把所有输入内容过滤一番就可以了。过滤输入内 容可以按多种方式进行。 ? 对于动态构造 SQL 查询的场合 a. 替换单引号,即把所有单独出现的单引号改成两个单引号,防止攻击者修改 SQL 命令的含 义。 b. 删除用户输入内容中的所有连字符 c. 对于用来执行查询的数据库帐户,限制其权限。用不同的用户帐户执行查询、插入、更新、 删除操作。 ? 用存储过程来执行所有的查询。 ? 限制表单或查询字符串输入的长度。 ? 检查用户输入的合法性。 ? 将用户登录名称、密码等数据加密保存。 ? 检查提取数据的查询所返回的记录数量。
14、简单描述 MySQL 中,索引,主键,唯一索引,联合索引的区别,对数据 库的性能有什么影响(从读写两方面)?
? 索引是一种特殊的文件(InnoDB 数据表上的索引是表空间的一个组成部分),它们包含着 对数据表里所有记录的引用指针。 ? 普通索引(由关键字 KEY 或 INDEX 定义的索引)的唯一任务是加快对数据的访问速度。 ? 普通索引允许被索引的数据列包含重复的值。如果能确定某个数据列将只包含彼此各不相 同的值,在为这个数据列创建索引的时候就应该用关键字 UNIQUE 把它定义为一个唯一 索引。也就是说,唯一索引可以保证数据记录的唯一性。 ? 主键,是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一 条记录,使用关键字 PRIMARY KEY 来创建。 ? 索引可以覆盖多个数据列,如像 INDEX(columnA, columnB)索引,这就是联合索引。 ? 索引可以极大的提高数据的查询速度,但是会降低插入、删除、更新表的速度,因为在执 行这些写操作时,还要操作索引文件。
15、幻读是什么,用什么隔离级别可以防止幻读?
幻读是一个事务在前后两次查询同一个范围的时候、后一次查询看到了前一次查询未看到的行。 在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的。因此,幻读在“当前读”下才会出现。 SERIALIZABLE(可串行化)可以防止幻读:最高的隔离级别,完全服从 ACID 的隔离级别。 所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰。
16、limit 1000000 加载很慢的话,你是怎么解决的呢?
方案一:如果 id 是连续的,可以这样,返回上次查询的最大记录(偏移量),再往下 limit select id,name from employee where id>1000000 limit 10. 方案二:在业务允许的情况下限制页数: 建议跟业务讨论,有没有必要查这么后的分页啦。因为绝大多数用户都不会往后翻太多页。 方案三:order by + 索引(id 为索引) select id,name from employee order by id limit 1000000,10 方案四:利用延迟关联或者子查询优化超多分页场景。(先快速定位需要获取的 id 段,然后 再关联) SELECT a.* FROM employee a, (select id from employee where 条件 LIMIT 1000000,10 ) b where a.id=b.id
17、什么是散列表? select * 和 select 1?
哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结 构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。 有时候为了提高效率,只是为了测试下某个表中是否存在记录,就用 1 来代替。
18、介绍下 MySQL 的主从复制原理?产生主从延迟的原因?
? 主从复制原理: 主库将变更写入 binlog 日志,然后从库连接到主库之后,从库有一个 IO 线程,将主库的 binlog 日志拷贝到自己本地,写入一个 relay 中继日志中。 接着从库 中有一个 SQL 线程会从中继日志读取 binlog,然后执行 binlog 日志中的内容,也就是 在自己本地再次执行一遍 SQL。 ? 主从延迟: a. 主库的从库太多 b. 从库硬件配置比主库差 c. 慢 SQL 语句过多 d. 主从库之间的网络延迟 e. 主库读写压力大
19、MySQL 中有哪几种锁?
? 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度 最低。 ? 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度 也最高。 ? 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之 间,并发度一般
|