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列的值,注意更新完成之后的结果请看第三个图:
执⾏结果如图
使用过哪些数据库的索引
从不同的角度描述有如下类型:
普通索引
唯一索引
复合索引
单列索引
主键索引
Mysql的主从复制是怎么实现的
- 主服务器开启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))
生产中是否使用过事务隔离级别 怎么使用的?当时遇到坑是怎么解决的?
默认是可重复读 ,不能解决幻读