mysql面试题mysql
1. 各个数据库存储引擎区别
mysql的存储引擎是针对表进行设置的,一个库的不一样表能够设置不一样的存储引擎,mysql默认支持多种存储引擎,以适用不一样领域的数据库应用须要,主要的几个数据库引擎以下:
MyISAM存储引擎
5.5以前默认的存储引擎,不支持事务、不支持外键,表级锁,内存和硬盘空间占用率低,其优点是访问速度快,对事务完整性没有要求,以select、insert为主的应用基本上均可以使用这个引擎;
InnoDB存储引擎
5.5以后默认的存储引擎,提供了具备提交、回滚和奔溃恢复能力的事务安全,支持外键并提供了行级锁,其劣势在于写的处理效率相对较低,而且会占用更多的磁盘空间以保留数据和索引;面试
MEMORY存储引擎
使用存于内存中的内容来建立表,MEMORY类型的表数据存于内存访问很是的快,默认使用HASH索引,一旦数据库服务重启或关闭,表中的数据就会丢失;
MERGE存储引擎
MERGE存储引擎是一组MyISAM表组合,这些MyISAM表结构彻底相同。MERGE表自己没有数据,对MERGE表的CRUD操做都是经过内部的MyISAM表进行的;redis
2. 提升sql 语句效率的技巧
大批量插入数据
大批量数据插入空表,可将表设置成为MyISAM,并经过disable keys将惟一索引关闭;
大批量数据插入非空Innodb表,可采起以下措施提升效率:
1. 导入数据时按照主键顺序排列;
2. 导入数据前使用set UNIQUE_CHECKS=0,关闭惟一性校验,导入后恢复;
3. 若是使用了自动提交,建议在导入前执行SET AUTOCOMMIT=0,关闭自动提交,导入后恢复;
优化INSERT 语句
尽可能使用多个值表的insert语句,下降链接、关闭的消耗;
将索引文件和数据文件分在不一样的磁盘上存放;
从一个文本文件装入一个表时,使用LOAD DATA INFLIE ,比通常的insert语句快20倍;sql
查询优化
尽可能减小额外的排序,经过索引直接返回有序数据;where条件和order by使用相同的索引,而且order by的顺序与索引顺序相同,而且order by的字段都是升序或者都是降序;
尽可能只选择必要的字段,提升sql性能;
能用关联查询的不要用子查询;
对于包含or的查询语句,若是要利用索引,则or之间的每一个条件都必须用到索引,不然应该考虑增长索引;
优化分页
在索引上完成排序分页的操做,而后根据主键关联回原表查询所需的其余列
把limit查询转换为某个位置的查询;mongodb
注意不使用索引的状况
若是MySQL估计使用索引比全表扫描更慢,则不使用索引。
用or分隔开的条件,若是or前的条件中的列有索引,然后面的列没有索引,那么涉及到的索引都不会被用到;
复合索引,若是索引列不是复合索引的第一部分,则不使用索引(即不符合最左前缀;
若是like是以’%’开始的,则该列上的索引不会被使用。
若是列为字符串,则where条件中必须将字符常量值加引号,不然即便该列上存在索引,也不会被使用;
not in 、 not exists 、 (<> 不等于 !=)这些操做符不走索引
不要在 where 子句中的“=”左边进行函数、算术运算或其余表达式运算,不然系统将可能没法正确使用索引;数据库
3. 怎么样作执行计划分析
经过explain命令获取mysql如何执行select语句的信息,包括在select语句执行过程当中表如何链接和链接的顺序;explain分析后的结果解析:
select_type
查询的类型,主要是用于区分普通查询、联合查询、子查询等复杂的查询
SIMPLE:简单的select查询,查询中不包含子查询或者union
PRIMARY:查询中包含任何复杂的子部分,最外层查询则被标记为primary
SUBQUERY:在select 或 where列表中包含了子查询
UNION:若第二个select出如今union以后,则被标记为union;若union包含在from子句的子查询中,外层select将被标记为derivedjson
type
访问类型,sql查询优化中一个很重要的指标,结果值从好到坏依次是:system > const > eq_ref > ref > range > index > ALL通常来讲,好的sql 查询至少达到range 级别,最好能达到ref ;
system:表只有一行记录(等于系统表),这是const类型的特例,平时不会出现,能够忽略不计
const:表示经过索引一次就找到了,const用于比较primary key 或者 unique索引。
eq_ref:惟一性索引扫描,对于每一个索引键,表中只有一条记录与之匹配(1对1);
ref:非惟一性索引扫描,返回匹配某个单独值的全部行。
range:索引范围扫描;
index:索引全扫描;
ALL:全表扫描;后端
possible_keys
查询涉及到的字段上存在索引,则该索引将被列出,但不必定被查询实际使用
key
实际使用的索引,若是为NULL,则没有使用索引。
key_len
表示索引中使用的字节数,查询中使用的索引的长度(最大可能长度),并不是实
际使用长度,理论上长度越短越好;
ref
显示索引的哪些列;
rows
根据表统计信息及索引选用状况,大体估算出找到所需的记录所须要读取的行数
Extra
不适合在其余字段中显示,可是十分重要的额外信息数组
优化目标 Tips:
1. 根据需求创建索引
2. 每一个查询都要使用索引以提升查询效率,至少达到range级别,最好能达到ref;
3. 追求key_len和rows最小;缓存
4. mysql 复制的原理
Mysql的复制原理大体以下:
1.主库在数据提交时会把数据变动做为事件记录在二进制日志文件Binlog中;可经过sync_binlog控制binlog日志刷新到磁盘的频率;
2.主库推送二进制日志文件binlog中的事件到从库的中继日志Relay Log,以后从库根据中继日志RelayLog重作数据变动操做,经过逻辑复制达到主从库的数据一致;
3.MySQL经过3个线程来完成主从库之间的数据同步,其中binlog dump线程跑在主库上,I/O线程和sql线程跑在从库上。
当从库启动复制时,首先建立I/O线程链接主库,主库随后建立binlog dump线程读取数据库事件并发送给I/O线程,I/O线程获取到事件数据后更新到从库的中继日志replay log中去,以后从库上的sql线程读取中继日志中更新的数据库事件并应用;
1. mongodb 与mysql 的区别?
mongodb的本质仍是一个数据库产品,3.0以上版本其稳定性和健壮性有很大提高。它与mysql的区别在于它不会遵循一些约束,好比:sql标准、ACID属性,表结构等。其主要特性以下:
面向集合文档的存储:适合存储Bson(json的扩展)形式的数据;
格式自由,数据格式不固定,生产环境下修改结构均可以不影响程序运行;
强大的查询语句,面向对象的查询语言,基本覆盖sql语言全部能力;
完整的索引支持,支持查询计划;
支持复制和自动故障转移;
支持二进制数据及大型对象(文件)的高效存储;
使用分片集群提高系统扩展性;
使用内存映射存储引擎,把磁盘的IO操做转换成为内存的操做;
2. mongoDB 主要使用在什么应用场景?
MongoDB 的应用已经渗透到各个领域,好比游戏、物流、电商、内容管理、社交、物联网、视频直播等,如下是几个实际的应用案例:
游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接之内嵌文档的形式存储,方便查询、更新
物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程当中会不断更新,以MongoDB 内嵌数组的形式来存储,一次查询就能将订单全部的变动读取出来。
社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,经过地理位置索引实现附近的人、地点等功能
物联网场景,使用 MongoDB 存储全部接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析
视频直播,使用 MongoDB 存储用户信息、礼物信息等
3. 怎么样作mongodb 查询优化
第一步 找出慢速查询
1. 开启内置的查询分析器,记录读写操做效率:
db.setProfilingLevel(n,{m}),n的取值可选0,1,2;
0是默认值表示不记录;
1表示记录慢速操做,若是值为1,m必须赋值单位为ms,用于定义慢速查询时间的阈值;
2表示记录全部的读写操做;
例如:db.setProfilingLevel(1,300)
2. 查询监控结果
监控结果保存在一个特殊的盖子集合system.profile里,这个集合分配了128kb的空间,要确保监控分析数据不会消耗太多的系统性资源;盖子集合维护了天然的插入顺序,可使用$natural操做符进行排序,如:db.system.profile.find().sort({'$natural':-1}).limit(5)
第二步 分析慢速查询
找出慢速查询的缘由比较棘手,缘由可能有多个:应用程序设计不合理、不正确的数据模型、硬件配置问题,缺乏索引等;接下来对于缺乏索引的状况进行分析:使用explain分析慢速查询
例如:db.orders.find({'price':{'$lt':2000}}).explain('executionStats')
explain的入参可选值为:
"queryPlanner" 是默认值,表示仅仅展现执行计划信息;
"executionStats" 表示展现执行计划信息同时展现被选中的执行计划的执行状况信息;
"allPlansExecution" 表示展现执行计划信息,并展现被选中的执行计划的执行状况信息,还展现备选的执行计划的执行状况信息;
第三步 解读explain结果
queryPlanner(执行计划描述)
winningPlan(被选中的执行计划)
stage(可选项:COLLSCAN 没有走索引;IXSCAN使用了索引)
rejectedPlans(候选的执行计划)
executionStats(执行状况描述)
nReturned (返回的文档个数)
executionTimeMillis(执行时间ms)
totalKeysExamined (检查的索引键值个数)
totalDocsExamined (检查的文档个数)
优化目标 Tips:
1. 根据需求创建索引
2. 每一个查询都要使用索引以提升查询效率, winningPlan. stage 必须为IXSCAN ;
3. 追求totalDocsExamined = nReturned
4. mongodb 的索引注意事项?
1. 索引颇有用,可是它也是有成本的——它占内存,让写入变慢;
2. mongoDB一般在一次查询里使用一个索引,因此多个字段的查询或者排序须要复合索引才能更加高效;
3. 复合索引的顺序很是重要
4. 在生成环境构建索引每每开销很大,时间也不能够接受,在数据量庞大以前尽可能进行查询优化和构建索引;
5. 避免昂贵的查询,使用查询分析器记录那些开销很大的查询便于问题排查;
6. 经过减小扫描文档数量来优化查询,使用explai对开销大的查询进行分析并优化;
7. 索引是用来查询小范围数据的,不适合使用索引的状况:
每次查询都须要返回大部分数据的文档,避免使用索引
写比读多
5. mongodb 是怎么实现高可用?
1. 结合项目经验,说下 redis 应用场景
缓存:合理使用缓存加快数据访问速度,下降后端数据源压力
排行榜:按照热度排名,按照发布时间排行,主要用到列表和有序集合
计数器应用:视频网站播放数,网站浏览数,使用redis计数
社交网络:赞、踩、粉丝、下拉刷新
消息队列:发布和订阅
2. redis 支持数据类型?各有什么特色?
String(字符串)
string类型是二进制安全的。意思是redis的string能够包含任何数据。好比jpg图片或者序列化的对象 。string类型是Redis最基本的数据类型,一个redis中字符串value最多能够是512M
Hash(哈希)
Redis hash 是一个键值对集合。Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。相似Java里面的Map<String,Object>
List(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。你能够添加一个元素导列表的头部(左边)或者尾部(右边),它的底层实际是个链表
Set(集合)
Redis的Set是string类型的无序集合。它是经过HashTable实现实现的,
zset(sorted set:有序集合)
Redis zset 和 set 同样也是string类型元素的集合,且不容许重复的成员。不一样的是每一个元素都会关联一个double类型的分数。redis正是经过分数来为集合中的成员进行从小到大的排序。zset的成员是惟一的,但分数(score)却能够重复。
3. 有什么持久化策略?各有什么特色
策略:支持RDB和AOF两种持久化机制,能够避免因进程退出形成数据丢失,特色以下:
RDB持久化把当前进程数据生成快照(.rdb)文件保存到硬盘的过程,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复。 优势在于使用单独子进程来进行持久化,主进程不会进行任何IO操做,保证了redis的高性能;缺点在于RDB是间隔一段时间进行持久化,若是持久化之间redis发生故障,会发生数据丢失。因此这种方式更适合数据要求不严谨的时候;有手动触发和自动触发,手动触发有save和
bgsave两命令 ;
save命令:阻塞当前Redis,直到RDB持久化过程完成为止,若内存实例比较大会形成长时间阻塞,线上环境不建议用它
bgsave命令:redis进程执行fork操做建立子线程,由子线程完成持久化,阻塞时间很短(微秒级),是save的优化,在执行redis-cli shutdown关闭redis服x务时,如
果没有开启AOF持久化,自动执行bgsave; 显然bgsave是对save的优化
AOF:针对RDB不适合实时持久化,redis提供了AOF持久化方式来解决,将“操做 +数据”以格式化指令的方式追加到操做日志文件的尾部,在append操做返回后(已经写入到文件或者即将写入),才进行实际的数据变动,“日志文件”保存了历史全部的操做过程;当server须要数据恢复时,能够直接replay此日志文件,便可还原全部的操做过程
开启:redis.conf设置:appendonly yes (默认不开启,为no)
默认文件名:appendfilename "appendonly.aof"
5. 介绍下哨兵机制
redis sentinel是一个分布式架构,其中包含了若干个sentinal节点和Redis节点,每一个sentinel节点会对数据节点和sentinel节点进行监控,当它发现节点不可达是,会对节点作下线标识。若是大部分sentinal节点认为主节点不可达,sentinal节点之间会进行“协商” ,选举出来一个sentinal节点完成故障转义,并同时把这个故障通知到应用方;
6. 介绍 redis 集群方案?以及其原理
RedisCluster是redis的分布式解决方案,在3.0版本后推出的方案,有效地解决了Redis分布式的需求,当遇到单机内存、并发等瓶颈时,可以使用此方案来解决这些问题,一个 redis 集群包含 16384 个哈希槽(hash slot),数据库中的每一个数据都属于这16384个哈希槽中的一个。集群使用公式(CRC16[key]&16383)函数来计算键 key属于哪一个槽。集群中的每个节点负责处理一部分哈希槽。
7. redis 能作读写分离吗?同步策略是怎么实现的?
redis提供了主从复制和哨兵机制来提升redis服务的健壮性和高可用,可是从严格意义上来说,redis并无实现读写分离,主从复制架构中,主节点用于响应读写请求,从节点用于数据备份,若是须要实现读从从节点读,应用须要对客户端进行改造;但在真实场景下通常不须要作此方案,读写分离主要应用在磁盘IO比较大的场景,而redis是缓存级别的
同步策略: redis 2.8版本以上使用psync命令完成同步,过程分“全量”与“部分”复制 a) 全量复制:通常用于初次复制场景(第一次创建SLAVE后全量) b) 部分复制:网络出现问题,从节占再次连主时,主节点补发缺乏的数据,每次数据增长同步