分享一下Java(MYSQL部分)面试心得

1.Mysql的索引类型,底层索引数据结构,用这个的好处,叶子节点存储的是什么,索引失效的原因

mysql的索引类型:主键索引,唯一索引,普通索引,全文索引。
添加普通索引: Alter table ‘table_name’ Add Index ‘index_name’(column1,column2,column3)
查询索引:Show Index From ‘table_name’
删除索引:Drop Index ‘index_name’ On ‘table_name’。
查看查询语句是否应用到索引:Explain Select * From ‘table_name’.使用Explain关键字加查询语句就可以看到。
底层索引数据结构:B+Tree
1.非叶子节点不存储data,只存储key。
2.叶子节点不存储指针。
3.顺时针访问指针,提高区间的性能。
B+Tree的索引性能分析
一般使用磁盘I/O次数评价索引结构的优劣
预读:磁盘一般会顺序向后读取一定长度的数据(页的整数倍)放入内存
局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用
B+Tree节点的大小设为等于一个页,每次新建节点直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,就实现了一个节点的载入只需一次I/O
B+Tree的度d一般会超过100,因此h非常小(一般为3到5之间)
索引失效的原因:
1.条件中有or
2.对于多列索引没有试用第一部分
3.like以%开头
4.如果类型为字符串,必须用引号引起来,也就是不需要类型转换。
5.where中索引列有了运算
6.where中使用了函数
7.数据少时,mysql会自动扫描全表。

2.如何优化sql,查询计划的结果中看哪些些关键数据

1.对查询进行优化,尽量避免全表扫描,对where和orde by涉及的列上建立索引。
2.尽量避免在where子句中对字段进行null判断,否则将会导致引擎放弃使用索引。.比如可以设置默认值,这样子就不用判空了。
3.尽量避免在where中使用or来连接条件.
4.避免在where子句中使用!=或者<>操作
5.in和not in也要慎用,能用between不用in。
6.like使用%开头
7.尽量避免where子句中使用函数,进行查询操作。
8.尽量避免在where子句中使用表达式操作。
9.不要在where子句中的‘=’左边进行函数,算术运算或其他表达式的运算。
10使用多列索引时,必须保证使用到该索引的第一个字段作为条件才能被系统使用。
11.不要写没意义的查询
12.很多时候可以用exists代替in
13不要对重复值多的列加索引
14.一张表最好不要加超过6个索引
15.尽量使用数字型的字段
16尽可能使用varcher代替char
17.任何地方都不能使用select *
18避免频繁创建和删除临时表,减少系统表资源的消耗。
19适当使用临时表
20如果需要新建表然后一次插入很多数据,可以用insert into代替create table,避免产生大量log。
21使用临时表后,必须truncate删除表
22避免使用游标
23基于集的方法通常比基于游标的方法或者临时表方法之前有效
24尽量避免大事务操作
25尽量避免向客户端返回大数据量。
大佬分析,走慢一点点
使用explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的,分析你的查询语句或是表结构的性能瓶颈。
好的sql查询至少达到range级别,最好能达到ref

3.innodb和myisam的区别

大佬的分析

4.mysql默认隔离级别,

大佬的图
mysql:四个事务隔离级别:读已提交,读未提交,可重复读,串行化。默认可重复读
sqlServer:默认系统事务隔离级别是read committed,也就是读已提交
oracle:默认系统事务隔离级别是READ COMMITTED,也就是读已提交
我们项目中一般使用读已提交,修改mysql的事务级别。

为什么mysql选择了可重复读作为默认的?

mysql在5.0以前binlog只支持STATEMENT这种格式,binlog就是用来做主从复制的。而这种格式在读已提交(Read Commited)这个隔离级别下主从复制是有bug的,就是主从表数据不一致,因此Mysql将可重复读(Repeatable Read)作为默认的隔离级别!

为什么互联网项目为什么将隔离级别设为读已提交?

ok,我们先明白一点!项目中是不用读未提交(Read UnCommitted)和串行化(Serializable)两个隔离级别,原因有二
采用读未提交(Read UnCommitted),一个事务读到另一个事务未提交读数据,这个不用多说吧,从逻辑上都说不过去!
采用串行化(Serializable),每个次读操作都会加锁,快照读失效,一般是使用mysql自带分布式事务功能时才使用该隔离级别!(笔者从未用过mysql自带的这个功能,因为这是XA事务,是强一致性事务,性能不佳!互联网的分布式方案,多采用最终一致性的事务解决方案!)
大佬的分析
缘由之一:在可重复读的级别上,会有间隙锁,出现死锁的问题比读已提交几率大的多。
在可重复读隔离级别下,条件列未命中索引会锁表!而在读已提交隔离级别下,只锁行。
在读已提交隔离级别下,半一致性读(semi-consistent)特性增加了update操作的并发性!

在读已提交的的隔离级别下,binlog是基于行的。

5.mysql的乐观锁和悲观锁,锁的种类

乐观锁,顾名思义,对加锁持有一种乐观的态度,即先进行业务操作,不到最后一步不进行加锁,"乐观"的认为加锁一定会成功的,在最后一步更新数据的时候在进行加锁,乐观锁的实现方式一般为每一条数据加一个版本号。
每次执行操作时,判断数据的版本号,不对的话就抛异常处理。

悲观锁对数据加锁持有一种悲观的态度。因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。
大佬的分析
悲观锁分为两种:共享锁和排它锁
共享锁是其它事务可以读但是不能写
排他锁是只有自己得事务有权限对此数据进行读写
加锁必须先开启事务:begin;(开启事务)->加锁、操作->commit;(提交事务,归还锁)

6.如何用sql实现乐观锁和悲观锁

悲观锁一定成功,但在并发量特别大的时候会造成很长堵塞甚至超时,仅适合小并发的情况。

乐观锁不一定每次都修改成功,但能充分利用系统的并发处理机制,在大并发量的时候效率要高很多。

7.mysql如何分库分表

垂直拆分和水平切分
大表切小表,基于字段进行的。将不常用,数据量较大的,长度较长拆分到拓展表中。几百列的大表一般是这种方式分。
垂直分库,不同的业务进行拆分。将多个库放在不同的服务器中,以免因为服务器的瓶颈造成数据库的反应迟钝。
水平拆分
1.水平分表
针对数据量巨大的表,按照某种规则,hash取模等切分到多张表里面去。
或按地区分表
分布式事务,

8.left join和inner join

left join:返回左表中所有记录和右表中联结字段相等的记录。
right join:返回右表中的所有记录与左边中联结字段的记录。
inner join 返回两个表中联结字段相等的行。

9.Mysql的基础面试题

DELETE语句执行删除的过程是每次从表中删除一行,并且同时将改行的删除事务记录在日志中保存以便进行回滚操作。
Drop语句将表所占的空间全部释放掉。
TRUNCATE 和DELETE只删除数据。
DROP是删除表数据加结构,表空间直接释放。

10mysql 的锁详解

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值