mysql面试题

01.Mysql

事务的几个级别

事务隔离级别脏读不可重复读幻读
读未提交(read-uncommitted)
读已提交(read-committed)
可重复读(repeatable-read)mysql默认级别
串行化(serializable)

脏读:一个事务读到了另外一个事务还未提交的数据

幻读:在一个事务中的两次select操作读取同一个表的记录数不同

使用MVCC可以解决幻读的问题

https://www.jianshu.com/p/8845ddca3b23

https://www.cnblogs.com/shoshana-kong/p/11244341.html(推荐看这个)

事务的特性:ACID

  • 原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
  • 一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
  • 隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
  • 持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。

mysql数据库常⽤的引擎

MyISAM,InnoDB,MEMORY

执⾏select count(*) from table哪种引擎速度快

MyISAM 因为会把每个表的总记录数保存起来

InnoDB不会保存,每次重新计算

Statement和PrepareStatement的区别

Preparestatement是预编译的,可以防止sql注入;可以缓存,执行效率比statement要高一些。

statement用户执行静态sql语句,不能防止sql注入;

Sql语句优化

  • 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描

  • 应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描

  • 应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
    select id from t where num=10 or num=20
    可以这样查询:
    select id from t where num=10
    union all
    select id from t where num=20

  • in 和 not in 也要慎用,否则会导致全表扫描,如:
    select id from t where num in(1,2,3)
    对于连续的数值,能用 between 就不要用 in 了:
    select id from t where num between 1 and 3

  • like后面的值不要用%开头,下面的查询也将导致全表扫描:
    select id from t where name like ‘%abc%’

  • 应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描

    select id from t where num/2=100
    应改为:
    select id from t where num=100*2

  • 应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
    select id from t where substring(name,1,3)=‘abc’–name以abc开头的id
    应改为:
    select id from t where name like ‘abc%’

  • 很多时候用 exists 代替 in 是一个好的选择:
    select num from a where num in(select num from b)
    用下面的语句替换:
    select num from a where exists(select 1 from b where num=a.num)

  • 并不是所有列上都适合建索引;,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

  • 索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,
    因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。
    一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

  • .尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。
    这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

  • .尽可能的使用 varchar 代替 char ,因为首先变长字段存储空间小,可以节省存储空间,
    其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

  • 任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

  • 如果删除数据库里的所有记录,使用truncate table,这个比delete table的效率高很多

关联子查询更新表

update tb_a out_ta 
set b= (select b from tb_b inner_b where out_ta.a=inner_b.a);

有两个表tb_a(数据参考第⼀个图)和tb_b(数据参考第⼆个图),可以是⽤两个表中的a列进⾏表关联,

要求使⽤tb_b表中的b列中的值,更新tb_a表中b列的值,注意更新完成之后的结果请看第三个图:

image-20210225105419473

image-20210225105430398

执⾏结果如图

image-20210225105446310

使用过哪些数据库的索引

从不同的角度描述有如下类型:

普通索引

唯一索引

复合索引

单列索引

主键索引

Mysql的主从复制是怎么实现的

image-20210225111008504

  • 主服务器开启binlog配置
  • 从服务器开启线程,从主服务的binlog中获取最新的操作日志
  • 从服务器获取到主服务器的binog日志后,生成relayLog(重做日志)
  • 从服务器根据relayLog重新操作一遍

说⼀下怎么防⽌超卖,SQL怎么写

update tb_boods set stock=stock-1 where stock>=1 and goods_id=123

去除一条重复记录

数据库3个字段,姓名,科⽬,分数,插⼊数据不⼩⼼插⼊了重复数据,怎么去重,重复数据保留⼀

个,SQL语句实现(delete from tb_user where id= (select a.id from (select count(id),id from

tb_user group by username,cls,score having count(id)>1 limit 0,1) a))

image-20210226144305686

生产中是否使用过事务隔离级别 怎么使用的?当时遇到坑是怎么解决的?

默认是可重复读 ,不能解决幻读

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值