面试|Mysql高频面试题(后端大数据面试必备)


文章目录

  • 1 B树和B+树的区别,为什么Mysql使用B+树
  • 2 Mysql锁有哪些,如何理解?
  • 3 索引的基本原理
  • 4 索引设计的原则?
  • 5 索引覆盖是什么
  • 6 最左前缀原则是什么
  • 7 lnnodb是如何实现事务的
  • 8 简述MylSAM和InnoDB的区别
  • 9 事务基本特性ACID分别是:
  • 10 什么是MVCC
  • 11 存储引擎的类型
  • 12 数据库表设计时,字段你会如何选择?
    • 1.字段类型优先级
    • 2.可以选整型就不选字符串
    • 3.够用就行不要慷慨
    • 4.尽量避免使用NULL
    • 5.char与varchar选择
  • 13 Mysql中VARCHAR(M)最多能存储多少数据?
  • 14 请说下事务的基本特性
  • 15 事务并发可能引发什么问题?
    • 脏读
    • 不可重复读
    • 幻读
  • 16 简述mysql中索引类型及对数据库的性能的影响
  • 17 简单描述下MySQL各种索引?
  • 18 索引设计的原则?
  • 19 什么是三星索引?
  • 20 mysql执行计划怎么看
  • 21 mysql聚簇和非聚簇索引的区别
  • 22 mysql索引的数据结构,各自优劣
  • 23 lnnoDB—棵B+树可以存放多少行数据?
    • 如何提高insert的性能?
  • 24 什么是全局锁、共享锁、排它锁?
  • 25 谈一下MySQL中的死锁
  • 26 sql的慢查询的优化?(面试我被问到)
  • 27 ACID靠什么保证的?
  • 28 mysql主从同步原理

1 B树和B+树的区别,为什么Mysql使用B+树 B树的特点:
1.节点排序
2.—个节点了可以存多个元素,多个元素也排序了
B+树的特点:
1.拥有B树的特点
2.叶子节点之间有指针
3.非叶子节点上的元素在叶子节点上都冗余了,也就是叶子节点中存储了所有的元素,并且排好顺序
Mysql索引使用的是B+树,因为索引是用来加快查询的,而B+树通过对数据进行排序所以是可以提高查询速度的,然后通过一个节点中可以存储多个元素,从而可以使得B+树的高度不会太高,在Mysql中一个nnodb页就是一个B+树节点,一个nnodb页默认16kb,所以一般情况下一颗两层的B+树可以存2000万行左右的数据,然后通过利用B+树叶子节点存储了所有数据并且进行了排序,并且叶子节点之间有指针,可以很好的支持全表扫描,范围查找等SQL语句
2 Mysql锁有哪些,如何理解? 按锁粒度分类:
1.行锁:锁某行数据,锁粒度最小。并发度高
2,表锁:锁整张表。锁粒度最大,并发度任3。间腺锁:锁的是一个区间
还可以分为:
1.共享锁:也就是读锁,一个事务给某行数据加了读锁,其他事务也可以读,但是不能写
2。排它锁:也就是写锁,一个事务给某行数据加了写锁,其他事务不能读,也不能写
还可以分为:
1.乐观锁:并不会真正的去锁某行记录,而是通过一个版本号来实现的
2.悲观锁:上面的行锁、表锁等都是悲观锁
3 索引的基本原理 索引用来快速地寻找那些具有特定值的记录。如果没有索引,一般来说执行查询时遍历整张表。
索引的原理:就是把无序的数据变成有序的查询
1.把创建了索引的列的内容进行排序
2.对排序结果生成倒排表
3.在倒排表内容上拼上数据地址链
4.在查询的时候,先拿到倒排表内容,再取出数据地址链,从而拿到具体数据
4 索引设计的原则? 查询更快、占用空间更小
1.适合索引的列是出现在where子句中的列,或者连接子句中指定的列
2.基数较小的表,索引效果较差,没有必要在此列建立索引
3,使用短索引,如果对长字符串列进行索引,应该指定一个前缀长度,这样能够节省大量索引空间,如果搜索词超过絷引前缀长度,则使用索引排除不四督的行,然后检查其余行是否可能匹配。
4,不要过度索引。索引需要额外的磁盘空间,并降低写操作的性能。在修改表内容的时候,索引会进行更新甚至重构,索引例越多,这个时间就会越长。所以只保持需要的索引有利于查询即可。
5,定义有外键的数据列一定要建立索引。
6,更新频繁字段不适合创建索引
7.若是不能有效区分数据的列不适合做索引列如性别,男女未知,最多也就三种,区分度实在太低)
5 索引覆盖是什么 索引覆盖就是一个SQL在执行时,可以利用索引来快速查找,并且此SQL所要查询的字段在当前索引对应的字段中都包含了,那么就表示此SQL走完索引后不用回表了,所需要的字段都在当前索引的叶子节点上存在,可以直接作为结果返回了
6 最左前缀原则是什么 当一个SQL想要利用索引是,就一定要提供该索引所对应的字段中最左边的字段,也就是排在最前面的字段,比如针对a.b.c三个字段建立了一个联合索引,那么在写一个sql时就一定要提供a字段的条件,这样才能用到联合索引,这是由于在建立abc三个字段的联合索引时,底层的B+树是按照abc三个字段从左往右去比较大小进行排序的,所以如果想要利用B+树进行快速查找也得符合这个规则
7 lnnodb是如何实现事务的 Innodb通过Buffer Pool,LogBuffer,Redo Log,Undo Log来实现事务,以一个update语句为例:
1.Innodb在收到一个update语句后,会先根据条件找到数据所在的页,并将该页缓存在Buffer Pool中
2.执行update语句,修改Buffer Pool中的数据,也就是内存中的数据
3.针对update语句生成一个RedoLog对象,并存入LogBuffer中
4.针对update语句生成undolog日志,用于事务回滚
5.如果事务提交,那么则把RedoLog对象进行持久化,后续还有其他机制将Buffer Pool中所修改的数据页持久化到磁盘中
6.如果事务回滚,则利用undolog日志进行回滚
8 简述MylSAM和InnoDB的区别 MylSAM:
不支持事务,但是每次查询都是原子的;
支持表级锁,即每次操作是对整个表加锁;
存储表的总行数;
一个MYISAM表有三个文件:索引文件、表结构文件、数据文件;
·采用非聚集索引,索引文件的数据域存储指向数据文件的指针。辅索引与主索引基本一致,但是辅索引不用保证唯一性.
lnnoDb:
支持ACID的事务,支持事务的四种隔离级别;
支持行级锁及外键约束:因此可以支持写并发;
不存储总行数;
一个nnoDb引擎存储在一个文件空间(共享表空间,表大小不受操作系统控制,一个表可能分布在多个文件里),也有可能为多个(设置为独立表空,表大小受操作系统文件大小限制,一般为2G),受操作系统文件大小的限制;
主键索引采用聚集索引(索引的数据域存储数据文件本身),辅索引的数据域存储主键的值; 因此从辅索引查找数据,需要先通过辅索引找到主键值,再访问辅索引; 最好使用自增主键,防止插入数据时,为维持B+树结构,文件的大调整。
9 事务基本特性ACID分别是: 原子性指的是一个事务中的操作要么全部成功,要么全部失败。
一致性指的是数据库总是从一个一致性的状态转换到另外一个一致性的状态。比如A转账给B10块钱,假设A只有9O块,支付之前我们数据库里的数据都是符合约束的但是如果事务执行成功了,我们的数据库数据就破坏约束了,因此事务不能成功,这里我们说事务提供了一致性的保证
隔离性指的是一个事务的修改在最终提交前,对其他事务是不可见的。
持久性指的是一旦事务提交,所做的修改就会永久保存到数据库中。
隔离性有4个隔离级别,分别是:
read uncommit读未提交,可能会读到其他事务未提交的数据,也叫做脏读。
用户本来应该读取到d=1的用户age应该是10,结果读取到了其他事务还没有提交的事务,结果读取结果age=20,这就是脏读。
read commit读已提交,两次读取结果不一致,叫做不可重复读。
不可重复读解决了脏读的问题,他只会读取已经提交的事务。
用户开启事务读取id=1用户,查询到age=10,再次读取发现结果=20,在同一个事务里同一个查询读取到不同的结果叫做不可重复读。
repeatable read可重复复读,这是mysql的默认级别,就是每次读取结果都一样,但是有可能产生幻读。
.serializable 串行,一般是不会使用的,他会给每一行读取的数据加锁,会导致大量超时和锁竞争的问题。
10 什么是MVCC MVCC(Mult-Vversion Concurrency Contral,多版本并发控制)指的就是在使用READCOMMITTD、REPEATABLEREAD这两种隔离级别的事务在执行普通的SECT操作时访问记录的版本链的过程。可以使不同事务的读-写、写-读操作并发执行,从而提升系统性能。READ COMMTTD、REPEATABLEREAD这两个隔离级别的一个很大不同就是:生成ReadView的时机不同,READ COMMTTD在每一次进行普通SELECT操作前都会生成一个Readview,而RFEPEATABLEREAD只在第一次进行普通SELET操作前生成-个ReadView,之后的查询操作都重复使用这个ReadView就好了。
11 存储引擎的类型 lnnoDB存储引擎
InnoDB是MySQL的默认事务型引擎,也是最重要、使用最广泛的存储引擎。它被设计用来处理大量的短期(short-lived)事务,应该优先考虑InnoDB引擎。MylSAM存储引擎
在MySQL5.1及之前的版本,MylSAM是默认的存储引擎。但是MylSAM不支持事务和行级锁,而且崩溃后无法安全恢复。
同时MylSAM对整张表加锁,很容易因为表锁的问题导致典型的的性能问题。
Memory引擎
Memory表至少比MylSAM表要快一个数量级,数据文件是存储在内存中。Memory表的结构在重启以后还会保留,但数据会丢失。
Memroy表在很多场景可以发挥好的作用:
用于查找(lookup)或者映射(mapping)表,例如将邮编和州名映射的表。用于缓存周期性聚合数据(periodically aggregated data)的结果。
用于保存数据分析中产生的中间数据。
Archive引擎
Archive存储引擎只支持INSERT和SELECT操作,会缓存所有的写并利用zlib对插入的行进行压缩,所以比MylSAM表的磁盘I/O更少。但是每次SELECT查询都需要执行全表扫描。
所以Archive表适合日志和数据采集类应用。
CSV引擎
CSV引擎可以将普通的CSV文件(逗号分割值的文件)作为MySQL的表来处理,但这种表不支持索引。
因此CSV引擎可以作为一种数据交换的机制,非常有用。
12 数据库表设计时,字段你会如何选择? 1.字段类型优先级 整型> date,time > enum char > varchar > blob,text选用字段长度最小、优先使用定长型、数值型字段中避免使用
"ZEROFILL”。
time :定长运算快,节省时间,考虑时区,写sql不方便
enum:能约束值的目的,内部用整形来储存,但与char联查时,内部要经历串与值的转化char :定长,考虑字符集和校对集
varchar:不定长,要考虑字符集的转换与排序时的校对集,速度慢text,blob :无法使用内存临时表(排序操作只能在磁盘上进行)
注意: date,time的选择可以直接选择使用时间戳,enum(“男”“女”)//内部转成数字来储存,多了一个转换的过程,可以使用tinyint代替最好使用tinyint。
2.可以选整型就不选字符串 整型是定长的,没有国家/地区之分,没有字符集差异。例如:
tinyint和char(1)从空间上看都
是一字节,但是order by排序tinyint 快。原因是后者需要考虑字符集与校对集(就是排序优先集)。
3.够用就行不要慷慨 大的字段影响内存影响速度。以年龄为例:tinyint unsigned not null; 可以储存255岁,足够了,用int浪费3个字节。以varchar(10),varchar(300)储存的内容相同,但在表中查询时,
varhcar(300)要花用更多内存。
4.尽量避免使用NULL Null不利于索引,也不利于查询。=null或者!= null都查询不到值,只有使用is null或者is notnull才可以。因此可以在创建字段时候使用not null default ""的形式。
5.char与varchar选择 char长度固定,处理速度要比varchar快很多,但是相对较费存储空间; 所以对存储空间要求不大,但在速度上有要求的可以使用char类型,反之可以用varchar类型。
13 Mysql中VARCHAR(M)最多能存储多少数据? 对于VARCHAR(M)类型的列最多可以定义65535个字节。其中的M代表该类型最多存储的字符数量,但在实际存储时并不能放这么多。
MySQL对一条记录占用的最大存储空间是有限制的,除了BLOB或者TEXT类型的列之外,其他所有的列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过65535个字节。
14 请说下事务的基本特性 事务应该具有4个属性:原子性、一致性、隔离性、持久性。
这四个属性通常称为ACID特性。
原子性指的是一个事务中的操作要么全部成功,要么全部失败。
一致性指的是数据库总是从一个一致性的状态转换到另外一个一致性的状态。比如A转账给B100块钱,假设中间sql执行过程中系统崩溃A也不会损失100块,因为事务没有提交,修改也就不会保存到数据库。
隔离性指的是一个事务的修改在最终提交前,对其他事务是不可见的。
持久性指的是一旦事务提交,所做的修改就会永久保存到数据库中。
15 事务并发可能引发什么问题? 脏读 1、在事务A执行过程中,事务A对数据资源进行了修改,事务B读取了事务A修改后的数据。
2、由于某些原因,事务A并没有完成提交,发生了RollBack操作,则事务B读取的数据就是脏数据。
这种读取到另一个事务未提交的数据的现象就是脏读(Dirty Read)。
不可重复读 事务B读取了两次数据资源,在这两次读取的过程中事务A修改了数据,导致事务B在这两次读取出来的数据不一致。
这种在同一个事务中,前后两次读取的数据不一致的现象就是不可重复读(NonrepeatableRead).
幻读 事务B前后两次读取同一个范围的数据,在事务B两次读取的过程中事务A新增了数据,导致事务B后一次读取到前一次查询没有看到的行。
幻读和不可重复读有些类似,但是幻读强调的是集合的增减,而不是单条数据的更新
16 简述mysql中索引类型及对数据库的性能的影响 普通索引:允许被索引的数据列包含重复的值。
唯—索引:可以保证数据记录的唯一性。I
主键:是一种特殊的唯一索引,在一张表中只能定义一个主键索引,主键用于唯一标识一条记录,使用关键字PRIMARY KEY来创建。
联合索引:索引可以覆盖多个数据列,如像INDEX(columnA, columnB)索引。
全文索引:通过建立倒排索引,可以极大的提升检索效率解决判断字段是否包含的问题,是目前搜索引擎使用的一种关键技术。可以通过ALTER TABLE table_name ADD FULLTEXT (column); 创建全文索引
优点:索引可以极大的提高数据的查询速度。
通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。
但是会降低插入、删除、更新表的速度,因为在执行这些写操作时,还要操作索引文件
缺点:索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大,如果非聚集索引很多,一旦聚集索引改变,那么所有非聚集索引都会跟着变。
17 简单描述下MySQL各种索引? MySQL索引按字段特性分类可分为:主键索引、普通索引、前缀索引
1.主键索引
建立在主键上的索引被称为主键索引,一张数据表只能有一个主键索引,索引列值不允许有空值,通常在创建表时一起创建。
2.唯一索引
建立在UNIQUE字段上的索引被称为唯一索引,一张表可以有多个唯一索引,索引列值允许为空,列值中出现多个空值不会发生重复冲突。
3.普通索引
建立在普通字段上的索引被称为普通索引。
4.前缀索引
前缀索引是指对字符类型字段的前几个字符或对二进制类型字段的前几个bytes建立的索引,而不是在整个字段上建索引。前缀索引可以建立在类型为char、varchar、binary、varbinary的列上,可以大大减少索引占用的存储空间,也能提升索引的查询效率。
前缀索引是一种能使索引更小更快的有效方法,但是也包含缺点: mysql无法使用前缀索引做order by 和group by
18 索引设计的原则? 查询更快、占用空间更小
1.适合索引的列是出现在where子句中的列,或者连接子句中指定的列2.基数较小的类,索引效果较差,没有必要在此列建立索引
3.使用短索引,如果对长字符串列进行索引,应该指定一个前缀长度,这样能够节省大量索引空间,如果搜索词超过索引前缀长度,则使用索引排除不匹配的行,然后检查其余行是否可能匹配。
4.不要过度索引。索引需要额外的磁盘空间,并降低写操作的性能。在修改表内容的时候,索引会进行更新甚至重构,索引列越多,这个时间就会越长。所以只保持需要的索引有利于查询即可。
5.定义有外键的数据列一定要建立索引。
6.更新频繁字段不适合创建索引
7.若是不能有效区分数据的列不适合做索引列(如性别,男女未知,最多也就三种,区分度实在太低)
8.尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。
9.对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。10.对于定义为text、image和bit的数据类型的列不要建立索引。
19 什么是三星索引? 对于一个查询而言,一个三星索引,可能是其最好的索引。
如果查询使用三星索引,一次查询通常只需要进行一次磁盘随机读以及一次窄索引片的扫描,因此其相应时间通常比使用一个普通索引的响应时间少几个数量级。
一个查询相关的索引行是相邻的或者至少相距足够靠近的则获得一星; 如果索引中的数据顺序和查找中的排列顺序一致则获得二星;
如果索引中的列包含了查询中需要的全部列则获得三星。
三星索引在实际的业务中如果无法同时达到,一般我们认为第三颗星最重要,第一和第二颗星重要性差不多,根据业务情况调整这两颗星的优先度。
20 mysql执行计划怎么看 执行计划就是sql的执行查询的顺序,以及如何使用索引查询,返回的结果集的行数EXPLAIN SELECT* from A where x=? and Y=?
1。id :是一个有顺序的编号,是查询的顺序号,有几个select就显示几行。id的顺序是按select 出现的
顺序增
长的。id列的值越大执行优先级越高越先执行,id列的值相同则从上往下执行,id列的值为NULL最后执行
2。selectType表示查询中每个select子句的类型
. SIMPLE:表示此查询不包含UNION查询或子查询.PRIMARY:表示此查询是最外层的查询(包含子查询). SUBQUERY:子查询中的第一个SELECT
· UNION:表示此查询是UNION的第二或随后的查询
.DEPENDENT UNION: UNION中的第二个或后面的查询语句,取决于外面的查询.UNION RESULT,UNION的结果
. DEPENDENT SUBQUERY:子查询中的第一个SELECT,取决于外面的查询.即子查询依赖于外层查间的结果.·DERIVED:衍生,表示导出表的SELECT (FROM子句的子查询)
3.table:表示该语句查询的表
4.type:优化sal的重要字段,也是我们判断sal性能和优化程度重要指标。
他的取值类型范围:
const:通过索引一次命中,匹配一行数据
system:表中只有一行记录,相当于系统表;
eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配. ref:非唯一性索引扫描,返回匹配某个值的所有
range:只检索给定范围的行,使用一个索引来选择行,一般用于between、<、>; · index:只遍历索引树;
ALL:表示全表扫描,这个类型的查询是性能最差的查询之一。那么基本就是随着表的数量增多,执行效率越慢。
执行效率:
ALL 5.possible_keys: 它表示Mysql在执行该sql语句的时候,可能用到的索引信息,仅仅是可能,实际不一定会用到。
6.key: 此字段是mysql在当前查询时所真正使用到的索引。他是possible_keys的子集
7.key_len:表示查询优化器使用了索引的字节数,这个字段可以评估组合索引是否完全被使用,这也是我们优化sql时,评估索引的重要指标
9.rows: mysq|查询优化器根据统计信息,估算该sql返回结果集需要扫描读取的行数,这个值相关重要,
索引优
化之后,扫描读取的行数越多,说明索引设置不对,或者字段传入的类型之类的问题,说明要优化空间越大
10.filtered:返回结果的行占需要读到的行(rows列的值)的百分比,就是百分比越高,说明需要查询到数据越准确,百分比越小,说明查询到的数据量大,而结果集很少
11.extra
using filesort :表示mysq|对结果集进行外部排序,不能通过索引顺序达到排序效果。一般有using filesort都建议优化去掉,因为这样的查询cpu资源消耗大,延时大。
using index:覆盖索引扫描,表示查询在索引树中就可查找所需数据,不用扫描表数据文件,往往说明性能不错。
ousing temporary: 查询有使用临时表,一般出现于排序,分组和多表join 的情况,查询效率不高,建议优化。
using where : sql使用了where过滤,效率较高。
21 mysql聚簇和非聚簇索引的区别 都是B+树的数据结构
·聚簇索引∶将数据存储与索引放到了一块、并且是按照一定的顺序组织的,找到索引也就找到了数据
数据的
物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的·非聚簇索引:叶子节点不存储数据、存储的是数据行地址,也就是说根据索引查找到数据行的位置再取磁盘查找数据,这个就有点类似一本树的目录,比如我们要找第三章第一节,那我们先在这个目录里面找,找到对应的页码后再去对应的页码看文章。
优势:
1、查询通过聚簇索引可以直接获取数据,相比非聚簇索引需要第二次查询(非覆盖索引的情况下)效率要高2、聚簇索引对于范围查询的效率很高,因为其数据是按照大小排列的
3、聚簇索引适合用在排序的场合,非聚簇索引不适合
劣势:
1、维护索引很昂贵,特别是插入新行或者主键被更新导至要分页(page split)的时候。建议在大量插入新行后,选在负载较低的时间段,通过OPTIMIZE TABLE优化表,因为必须被移动的行数据可能造成碎片。使用独享表空间可以弱化碎片
2、表因为使用UUTd((随机ID〉作为主键,使数据存储稀疏,这就会出现聚簇索引有可能有比全表扫面更慢,所以建议使用int的auto_increment作为主键
3、如果主键比较大的话,那辅助索引将会变的更大,因为辅助索引的叶子存储的是主键值; 过长的主键值,会导致非叶子节点占用占用更多的物理空间
InnoDB中一定有主键,主键一定是聚簇索引,不手动设置、则会使用unique索引,没有unique索引,则会使用数据库内部的一个行的隐藏id来当作主键索引。在聚簇索引之上创建的索引称之为辅助索引,辅助索引访问数据总是需要二次查找,非聚簇索引都是辅助索引,像复合索引、前缀索引、唯一索引,辅助索引叶子节点存储的不再是行的物理位置,而是主键值
MyISM使用的是非聚簇索引,没有聚簇索引,非聚簇索引的两棵B+树看上去没什么不同,节点的结构完全一致,只是存储的内容不同而已,主键索引B+树的节点存储了主键,辅助键索引B+树存储了辅助键。表数据存储在独立的地方,这两颗B+树的叶子节点都使用一个地址指向真正的表数据,对于表数据来说,这两个键没有任何差别。由于索引树是独立的,通过辅助键检索无需访问主键的索引树。
如果涉及到大数据量的排序、全表扫描、count之类的操作的话,还是MyISAM占优势些,因为索引所占空间小,这些操作是需要在内存中完成的。
22 mysql索引的数据结构,各自优劣 索引的数据结构和具体存储引擎的实现有关,在MySQL中使用较多的索引有Hash索引,B+树索引等,lnnoDB存储引擎的默认索引实现为:B+树索引。对于哈希索引来说,底层的数据结构就是哈希表,因此在绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快; 其余大部分场景,建议选择BTree索引。
B+树:
B+树是一个平衡的多又树,从根节点到每个叶子节点的高度差值不超过1,而且同层级的节点间有指针相互链接。在B+树上的常规检索,从根节点到叶子节点的搜索效率基本相当,不会出现大幅波动,而且基于索引的顺序扫描时,也可以利用双向指针快速左右移动,效率非常高。因此,B+树索引被广泛应用于数据库、文件系统等场景。
哈希索引:
哈希索引就是采用一定的哈希算法。把键值换算成新的哈希值,检索时不需要类似B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可立刻定位到相应的位置,速度非常快
如果是等值查询,那么哈希索引明显有绝对优势,因为只需要经过一次算法即可找到相应的键值; 前提是键值都是唯一的。如果键值不是唯一的,就需要先找到该键所在位置,然后再根据链表往后扫描,直到找到相应的数据; 如果是范围查询检索,这时候哈希索引就毫无用武之地了,因为原先是有序的键值,经过哈希算法后,有可能变成不连续的了,就没办法再利用索引完成范围查询检索;
哈希索引也没办法利用索引完成排序,以及like 'xxx%'这样的部分模糊查询(这种部分模糊查询,其实本质上也是范围查询);
哈希索引也不支持多列联合索引的最左匹配规则;
B+树索引的关键字检索效率比较平均,不像B树那样波动幅度大,在有大量重复键值情况下,哈希索引的效率也是极低的,因为存在哈希碰撞问题。
23 lnnoDB—棵B+树可以存放多少行数据? 这个问题的其实非常简单:约2千万
计算机在存储数据的时候,有最小存储单元,在计算机中磁盘存储数据最小单元是扇区(这就好比我们今天进行现金的流通最小单位是一毛),一个扇区的大小是512字节,而文件系统(例如XFS/EXI4)的最小单元是块,一个块的大小是4k,而对于我们的InnoDB存储引擎也有自己的最小储存单元——页(Page) ,一个页的大小是16K。
Innodb的所有数据文件(后缀为ibd的文件),他的大小始终都是16384 (16k))的整数倍。
数据表中的数据都是存储在页中的,所以一个页中能存储多少行数据呢?假设一行数据的大小是1k,那么一个页可以存放16行这样的数据。
对于B+树而言,只有叶子节点存放数据,非叶子节点存放的是只保存索引信息和下一层节点的指针信息。一个非叶子节点能存放多少指针?
其实这也很好算,我们假设主键 ID为常用的bigint类型,长度为8字节,而指针大小在
InnoDB源码中设置为6字节,这样一共14字节,我们一个页中能存放多少这样的单元,其实就代表有多少指针,即16384/14=1170个。
那么可以算出一棵高度为2的B+树,存在一个根节点和若干个叶子节点能存放117016=18720条这样的数据记录。
根据同样的原理我们可以算出一个高度为3的B+树可以存放
1170
11 70*16=21902400条这样的记录。
如何提高insert的性能? 1、合并多条insert为一条
即: insert into t values(a,b,c),(d,e,f) .
原因分析:主要原因是多条insert合并后日志量(MySQL的binlog和innodb的事务日志)减少了,降低日志刷盘的数据量和频率,从而提高效率。通过合并SQL语句,同时也能减少SQL语句解析的次数,减少网络传输的IO。
2、修改参数bulk_insert_buffer_size,调大批量插入的缓存;
3、设置innodb_flush_log_at_trx_commit= o
相对于innodb_flush_log_at_trx_commit = 1可以十分明显的提升导入速度;
0: log buffer中的数据将以每秒一次的频率写入到log file中,
且同时会进行文件系统到磁盘的
同步操作,但是每个事务的commit并不会触发任何log buffer到log file 的刷新或者文件系统到磁盘的刷新操作;
1:在每次事务提交的时候将log buffer 中的数据都会写入到log file,同时也会触发文件系统到磁盘的同步;
2:事务提交会触发log buffer到log file的刷新,但并不会触发磁盘文件系统到磁盘的同步。此外,每秒会有一次文件系统到磁盘同步操作。
4、手动使用事务
因为mysql默认是autocommit的,这样每插入一条数据,都会进行一次commit; 所以,为了减少创建事务的消耗,我们可用手工使用事务
即START TRANSACTION; insert 。, ,insert, 。 commit;
即执行多个insert后再一起提交; 一般1000条insert提交一次。
24 什么是全局锁、共享锁、排它锁? 全局锁就是对整个数据库实例加锁,它的典型使用场景就是做全库逻辑备份。这个命令可以使整个库处于只读状态。使用该命令之后,数据更新语句、数据定义语句、更新类事务的提交语句等操作都会被阻塞。
共享锁又称读锁(read lock),是读取操作创建的锁。其他用户可以并发读取数据,但任何事务都不能对数据进行修改(获取数据上的排他锁),直到已释放所有共享锁。当如果事务对读锁进行修改操作,很可能会造成死锁。
排他锁exclusive lock(也叫writer lock)又称写锁。
若某个事物对某一行加上了排他锁,只能这个事务对其进行读写,在此事务结束之前,其他事务不能对其进行加任何锁,其他进程可以读取,不能进行写操作,需等待其释放。排它锁是悲观锁的一种实现。
若事务1对数据对象A加上X锁,事务1可以读A也可以修改A,其他事务不能再对A加任何锁,直到事物1释放A上的锁。这保证了其他事务在事物1释放A上的锁之前不能再读取和修改A。排它锁会阻塞所有的排它锁和共享锁
25 谈一下MySQL中的死锁 死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁。
如何查看死锁?
使用命令show engine innodb status查看最近的一次死锁。
InnoDB Lock Monitor打开锁监控,每15s输出一次日志。使用完毕后建议关闭,否则会影响数据库性能。
对待死锁常见的两种策略:
通过innodblockwait_timeout来设置超时时间,一直等待直到超时;
发起死锁检测,发现死锁之后,主动回滚死锁中的某一个事务,让其它事务继续执行。
26 sql的慢查询的优化?(面试我被问到) 在业务系统中,除了使用主键进行的查询,其他的都会在测试库上测试其耗时,慢查询的统计主要由运维在做,会定期将业务中的慢查询反馈给我们。
慢查询的优化首先要搞明白慢的原因是什么?是查询条件没有命中索引?是load了不需要的数据列?还是数据量太大?
所以优化也是针对这三个方向来的,
·首先分析语句,看看是否load了额外的数据,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写。
·分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或者修改索引,使得语句可以尽可能的命中索引。
·如果对语句的优化已经无法进行,可以考虑表中的数据量是否太大,如果是的话可以进行横向或者纵向的分表。
27 ACID靠什么保证的? A原子性由undo log日志保证,它记录了需要回滚的日志信息,事务回滚时撤销已经执行成功的sql
C一致性由其他三大特性保证、程序代码要保证业务上的一致性
l隔离性由MVCC来保证
D持久性由内存+redo log来保证,mysq]修改数据同时在内存和redo log记录这次操作,宕机的时候可以从redolog恢复
InnoDB redo 1og写盘,InnoDB事务进入 prepare状态。
如果前面 prepare成功,bin1og写盘,再继续将事务日志持久化到 bin1og,如果持久化成功,那么、InnoDB事务则进入commit状态(在 redo log里面写一个 commit记录)
redolog的刷盘会在系统空闲时进行
28 mysql主从同步原理 mysql主从同步的过程:
Mysql的主从复制中主要有三个线程: master (bin1og dump thread), slave (I/o thread , SQLthread), Master—条线程和Slave中的两条线程。
·主节点binlog,主从复制的基础是主库记录数据库的所有变更记录到binlog。binlog是数据库服务器启动的那一刻起,保存所有修改数据库结构或内容的一个文件。
·主节点log dump线程,当binlog有变动时,log dump线程读取其内容并发送给从节点。
·从节点I/o线程接收binlog内容,并将其写入到relay log 文件中。
·从节点的SQL线程读取relay log文件内容对数据更新进行重放,最终保证主从数据库的一致性。
注:主从节点使用 binglog文件+ position偏移量来定位主从同步的位置,从节点会保存其已接收到的偏移量,如果从节点发生宕机重启,则会自动从position的位置发起同步。
由于mysql默认的复制方式是异步的,主库把日志发送给从库后不关心从库是否已经处理,这样会产生一个问题就是假设主库挂了,从库处理失败了,这时候从库升为主库后,日志就丢失了。由此产生两个概念。
全同步复制
主库写入binlog后强制同步日志到从库,所有的从库都执行完成后才返回给客户端,但是很显然这个方式的话性能会受到严重影响。
半同步复制
和全同步不同的是,半同步复制的逻辑是这样,从库写入日志成功后返回ACK确认给主库,主库收到至少一个从库的确认就认为写操作完成。
/o线程接收binlog内容,并将其写入到relay log 文件中。
·从节点的SQL线程读取relay log文件内容对数据更新进行重放,最终保证主从数据库的一致性。
注:主从节点使用 binglog文件+ position偏移量来定位主从同步的位置,从节点会保存其已接收到的偏移量,如果从节点发生宕机重启,则会自动从position的位置发起同步。
由于mysql默认的复制方式是异步的,主库把日志发送给从库后不关心从库是否已经处理,这样会产生一个问题就是假设主库挂了,从库处理失败了,这时候从库升为主库后,日志就丢失了。由此产生两个概念。
全同步复制
主库写入binlog后强制同步日志到从库,所有的从库都执行完成后才返回给客户端,但是很显然这个方式的话性能会受到严重影响。
【面试|Mysql高频面试题(后端大数据面试必备)】半同步复制
和全同步不同的是,半同步复制的逻辑是这样,从库写入日志成功后返回ACK确认给主库,主库收到至少一个从库的确认就认为写操作完成。

    推荐阅读