文章目录
1.请你谈谈 MySQL 事务隔离级别,MySQL 的默认隔离级别是什么?
2、可重复读解决了哪些问题?
3、对 SQL 慢查询会考虑哪些优化 ?
4、MySQL 为什么 InnoDB 是默认引擎?
5、MySQL 索引底层结构为什么使用 B+树?
6、B+ 树的叶子节点链表是单向还是双向?
7、如何查询慢 SQL 产生的原因
8、索引失效的情况有哪些?
9、MySQL 事务的特性有什么,说一下分别是什么意思?
10、介绍下 MySQL 聚簇索引与非聚簇索引的区别(InnoDB 与 Myisam 引 擎)?
11、然后给一个联合索引(a,b)和一个语句,select * from table where b = ‘xxx’, 判断是否能命中索引?为什么?
12、MySQL 索引分类?
13、谈谈你对 SQL 注入式攻击的理解?
14、简单描述 MySQL 中,索引,主键,唯一索引,联合索引的区别,对数据 库的性能有什么影响(从读写两方面)?
15、幻读是什么,用什么隔离级别可以防止幻读?
16、limit 1000000 加载很慢的话,你是怎么解决的呢?
17、什么是散列表? select * 和 select 1?
18、介绍下 MySQL 的主从复制原理?产生主从延迟的原因?
19、MySQL 中有哪几种锁?
20.数据库三范式
21.mysql中int(10)和char(10)以及varchar(10)的区别
22. InnoDB 和 MyISAM 的区别
23. 索引在哪些情况下适合添加
24. 索引在哪些情况下不适合添加
25. EXPLAIN(执行计划)各列作用
26. 数据库服务器的优化步骤
27. MySQL 主从复制原理
1.请你谈谈 MySQL 事务隔离级别,MySQL 的默认隔离级别是什么?
为了达到事务的四大特性,数据库定义了 4 种不同的事务隔离级别:
READ-UNCOMMITTED(读取未提交):最低的隔离级别,允许脏读,也就是可能读取 到其他会话中未提交事务修改的数据,可能会导致脏读、幻读或不可重复读。 READ-COMMITTED(读取已提交): 只能读取到已经提交的数据。Oracle 等多数数 据库默认都是该级别 (不重复读),可以阻止脏读,但是幻读或不可重复读仍有可能发 生。 REPEATABLE-READ(可重复读):对同一字段的多次读取结果都是一致的,除非数据 是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。 SERIALIZABLE(可串行化):最高的隔离级别,完全服从 ACID 的隔离级别。所有的 事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏 读、不可重复读以及幻读。
MySQL 默认采用的 REPEATABLE_READ 隔离级别。
脏读:
1、在事务A执行过程中,事务A对数据资源进行了修改,事务B读取了事务A修改后的数据。
2、由于某些原因,事务A并没有完成提交,发生了RollBack操作,则事务B读取的数据就是脏数据。
这种读取到另一个事务未提交的数据的现象就是脏读(Dirty Read)。
事务B前后两次读取同一个范围的数据,在事务B两次读取的过程中事务A新增了数据,导致事务B后一次读取到前一次查询没有看到的行。
幻读和不可重复读有些类似,但是幻读强调的是集合的增减,而不是单条数据的更新。
不可重复读:
事务B读取了两次数据资源,在这两次读取的过程中事务A修改了数据,导致事务B在这两次读取出来的数据不一致。
在同一个事务中,前后两次读取的数据不一致的现象就是不可重复读(Nonrepeatable 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 中有哪几种锁?
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度 最低。
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度 也最高。
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之 间,并发度一般
20.数据库三范式
三范式总结
第一范式:需要满足列字段的原子性(不能再分) 第二范式:在满足第一范式的基础上列字段需要跟主键有直接关联关系(列字段依赖于主键,可以通过主键所代表的表对象,定义关联字段) 第三范式:在满足第一,第二范式的基础上,列字段不能冗余(可以通过表关联展示的字段,应放到关联表中)
21.mysql中int(10)和char(10)以及varchar(10)的区别
● int(10)的10表示显示的数据的长度,不是存储数据的大小;chart(10)和varchar(10)的10表示存储数据的大小,即表示存储多少个字符。
int(10) 10位的数据长度 9999999999,占32个字节,int型4位
char(10) 10位固定字符串,不足补空格 最多10个字符
varchar(10) 10位可变字符串,不足补空格 最多10个字符
● char(10)表示存储定长的10个字符,不足10个就用空格补齐,占用更多的存储空间
● varchar(10)表示存储10个变长的字符,存储多少个就是多少个,空格也按一个字符存储,这一点是和char(10)的空格不同的,char(10)的空格表示占位不算一个字符
22. InnoDB 和 MyISAM 的区别
1. 事务、分布式事务: InnoDB 支持 , MyISAM不支持 2. 锁:InnoDB:支持行锁 ;MyISAM:支持表锁 3. 外键: InnoDB 支持 , MyISAM不支持 4. 数据表结构: InnoDB: .frm 、 .ibd ; MyISAM: .frm 、 .myd 、.myi 5. 主键索引的不同:InnoDB:索引即数据;MyISAM:索引和数据是分开的 相同点:默认索引都使用B+树 6. 默认引擎 :5.5之前默认MyISAM ,5.5之后默认InnoDB 7. 开发中InnoDB :读写效率较 MyISAM差一些,占用空间大 MyISAM : 适合于小型设备,读写效率高,占用空间小
23. 索引在哪些情况下适合添加
1. 字段的数值有唯一性的限制 2. 频繁作为 WHERE 查询条件的字段,尤其在数据表大的情况下 3. 需要经常 GROUP BY 和 ORDER BY 的列 4. UPDATE、DELETE 的 WHERE 条件列,一般也需要创建索引 DISTINCT 字段需要创建索引 5. 做多表 JOIN 连接操作时(对用于连接的字段创建索引,并且该字段在多张表中的类型必须一致) 6. 尽量使用索引列的类型小的创建索引(指的就是该类型表示的数据范围的大小) 7. 尽量使用字符串前缀来索引 8. 组合索引把散列性高(区分度高)的值放在前面 9. 在多个字段都要创建索引的情况下,联合索引优于单值索引
24. 索引在哪些情况下不适合添加
1. 在where中使用不到的字段,不要设置索引 2. 数据量小的表最好不要使用索引 3. 有大量重复数据的列上不要建立索引 4. 避免对经常更新的表进行过多的索引 5. 不建议用无序的值作为索引 6. 删除不再使用或者很少使用的索引 7. 不要定义冗余或重复的索引 8. 限制索引的数目
25. EXPLAIN(执行计划)各列作用
1. table:将整个SQL语句分为多个单表访问的表,查询的每一行记录都对应着一个单表 2. id:在一个大的查询语句中每个SELECT关键字都对应一个唯一的id(优化器将子查询转换为连接查询除外) 3. select_type:SELECT关键字对应的那个查询的类型,确定小查询在整个大查询中扮演了一个什么角色 4. partition:匹配的分区信息 5. type:针对单表的访问方法 6. possible_keys和key:可能用到的索引 和 实际上使用的索引 7. key_len:实际使用到的索引长度 8. ref:当使用索引列等值查询时,与索引列进行等值匹配的对象信息 9. rows:预估的需要读取的记录条数 10. filtered: 某个表经过搜索条件过滤后剩余记录条数的百分比 11. Extra:一些重要的额外信息
26. 数据库服务器的优化步骤
1. 观察服务器运行状态是否存在周期性波动 2. 如果存在周期性波动,加缓存更改缓存失效策略 3. 如果不存在周期性波动,或者加缓存后仍然有延迟或者卡顿,就开启慢查询,使用 explain 查看 SQL 的执行细节 4. 如果 SQL 的等待时间长,就调优服务器参数 5. 如果 SQL 的执行时间长,就优化索引、优化多表 join,优化数据库表 6. 如果不是 SQL 的问题,说明 SQL 到达瓶颈,此时需要进行读写分离优化、分库分表优化
27. MySQL 主从复制原理
1.在主从复制过程中,会基于 3 个线程来操作,一个 主库线程 ,两个 从库线程 。
2.二进制日志转储线程(Binlog dump thread)是一个主库线程。当从库线程连接的时候, 主库可以将二进制日志发送给从库,当主库读取事件的时候,会在 Binlog 上加锁 ,读取完成之后,再将锁释放掉。
3.从库 I/O 线程会连接到主库,向主库发送请求更新 Binlog。这时从库的 I/O 线程就可以读取到主库的二进制日志转储线程发送的 Binlog 更新部分 ,并且拷贝到本地形成中继日志 (Relay log)。
4.从库 SQL 线程会读取从库中的中继日志,并且 执行日志中的事件 ,从而将从库中的数据与主库保持同步 。