mysql面试总结

最近一直在面试,总结下面试会被问到的关于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

你可能感兴趣的:(mysql)