最近一直在面试,总结下面试会被问到的关于mysql的知识点:
mysql锁机制:
表锁:开销小,加锁快;不会出现死锁;锁粒度大,发生锁冲突的概率最高,并发度最低。适合于以查询为主,只有少量按索引条件更新数据的应用,如web应用。
行锁:开销大、锁加慢;会出现死锁;锁粒度最小,发生锁冲突的概率最低,并发度也最高。适用于按大量索引条件并发更新少量不同数据,同时又有并发查询的应用。
GAP锁:开销和加锁的时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度依具体场景确定。
mysql性能优化:
1.explain
type列,连接类型。一个好的sql语句至少达到range级别。杜绝出现all级别。
key列,使用到的索引名。如果没有选择索引,值是NULL。可以采取强制索引方式。
key_len列,索引长度
rows列,扫描行数,该值是个预估值
extra列,详细说明。注意常见的不太友好的值有:Using filesort,Using temporary
2.sql语句中IN包含的值不应过多
MySQL对于IN做了相应的优化,即将IN中常量全部存储在一个数组里面,而且这个数组是排好序的。但是如果数值较多,产生的消耗也比较大。再例如:select id from table_name where num in(1,2,3) 对于连续的数值,能用 between 就不要用 in 了;再或者使用连接来替换。
3.select语句中务必指明字段
select * 增加很多不必要的消耗(cpu、io、内存、网络带宽);增加了使用覆盖索引的可能性;当表结构发生改变时,前段也需要更新。所以需要在select后面接上字段名。
4.当只需要一条数据时,使用limit1
这是为了使EXPLAIN中type列达到const类型
5.如果排序字段没有用到索引,就尽量少安排
6.如果限制条件中其他字段没有索引,尽量少用or
or两边的字段中,如果有一个不是索引字段,而其他条件也不是索引字段,会造成该查询不走索引的情况。很多时候使用union all或者是union(必要的时候)的方式来代替“or”会得到更好的效果。
7.尽量用union all 代替union
union 和 union all的差异主要是前者需要将结果集合后再进行唯一性过滤操作,这就会涉及到排序,增加大量CPU运算,加大资源消耗及延迟。当然,union all的前提条件就是两个结果没有重复数据。
8.不使用order by rand()
select id from `table_name` order by rand() limit 1000;
上面的sql语句可以优化为:
select id from `table_name` t1 join (select rand() * (select max(id) from `table_name`) as nid) t2 on t1.id > t2.nid limit 1000;
9.区分in和exists,not in 和not exists
select * from 表A where id in (select id from 表B)
上面sql语句相当于
select * from 表A where exists (select * from 表B where 表B.id=表A.id)
区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询。所以IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。
10.使用合理的分页方式以提高分页的效率
select id,name from table_name limit 866613, 20
使用上述sql语句做分页的时候,可能有人会发现,随着表数据量的增加,直接使用limit分页查询会越来越慢。
优化的方法如下:可以取前一页的最大行数的id,然后根据这个最大的id来限制下一页的起点。比如此列中,上一页最大的id是866612。sql可以采用如下的写法:
select id,name from table_name where id> 866612 limit 20
mysql索引:
1.普通索引
2.唯一索引
主键索引
唯一索引
3.联合索引
联合主键索引
联合唯一索引
联合普通索引
4.全文索引
用于搜索很长一篇文章时,效果最好
5.空间索引
索引结构:
https://www.cnblogs.com/ouhouki/articles/9668961.html
mysql分库分表:
垂直:分成不同的表,每个表的结构都不一样
水平:分成多个库,每个库的表结构都一直
https://www.cnblogs.com/butterfly100/p/9034281.html
两种数据库引擎的区别:
Innodb引擎概述
Innodb引擎提供了对数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别。该引擎还提供了行级锁和外键约束,它的设计目标是处理大容量数据库系统,它本身其实就是基于MySQL后台的完整数据库系统,MySQL运行时Innodb会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎不支持FULLTEXT类型的索引,而且它没有保存表的行数,当SELECT COUNT(*) FROM TABLE时需要扫描全表。当需要使用数据库事务时,该引擎当然是首选。由于锁的粒度更小,写操作不会锁定全表,所以在并发较高时,使用Innodb引擎会提升效率。但是使用行级锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表。
MyISAM引擎概述
MyISAM是MySQL默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键,因此当INSERT(插入)或UPDATE(更新)数据时即写操作需要锁定整个表,效率便会低一些。不过和Innodb不同,MyISAM中存储了表的行数,于是SELECT COUNT(*) FROM TABLE时只需要直接读取已经保存好的值而不需要进行全表扫描。如果表的读操作远远多于写操作且不需要数据库事务的支持,那么MyISAM也是很好的选择。
简单介绍区别:
1、MyISAM是非事务安全的,而InnoDB是事务安全的
2、MyISAM锁的粒度是表级的,而InnoDB支持行级锁
3、MyISAM支持全文类型索引,而InnoDB不支持全文索引
4、MyISAM相对简单,效率上要优于InnoDB,小型应用可以考虑使用MyISAM
5、MyISAM表保存成文件形式,跨平台使用更加方便
应用场景:
1、MyISAM管理非事务表,提供高速存储和检索以及全文搜索能力,如果再应用中执行大量select操作,应该选择MyISAM
2、InnoDB用于事务处理,具有ACID事务支持等特性,如果在应用中执行大量insert和update操作,应该选择InnoDB
转自:https://blog.csdn.net/printwsl/article/details/80058841