1、mysql中的慢查询
查询时间很长
a.开启慢查询日志
set global slow_query_log = ON
set global long_query_time = 3600'
set global log_queryrise_not_using_indexes = ON;
b.分析慢查询日志 使用explain 关键字
c.常见慢查询优化
将字段很多的表分解成多个表
(对于字段较多的表,如果有些字段的使用频率很低,可以将这些字段分离出来形成新表)
分解关联查询
优化limit分页
2、事物的隔离级别
Serializable 串行化,一个事务一个事务的执行
Repeatable read 可重复读,无论其它事务是否修改并提交数据,在这个事务中看到的数据值始终不受其他事务的影响
Read committed 读取已提交,其他事务提交了对数据修改后的数据,本事务也能看见 修改后的值 乐观锁 采用此种方式
Read uncommitted 读取未提交,其他事务只要修改了数据,即使未提交,本事务也能看见修改后的数据
3、数据库3范式
INF(无重复的列)
2NF(属性完全依赖于主键)
3NF(属性不传递依赖于其它非主属性)
4、sql优化:
1.了解什么是执行计划
执行计划是数据库根据sql语句相关表的统计信息作出的一分查询方案
查询优化器:例如 一条SQL语句要在10条数据中查询一条记录,那么查询将采用索引的方式进行查找。
如果该表进行了归档,只剩5000条数据,那查询优化器将采用‘全表扫描’的方式
2.统一sql语句的写法,例如大小写
3.查询语句不要太复杂
(执行计划是可以被重用的,越简单的sql语句被重用的可能性越高
4.使用临时表 暂存中间结果
(可以避免程序中多次扫描主表,也大大减少了程序执行中‘共享锁’阻塞‘更新锁’。减少了阻塞,提高了并发性能;
5. 最左匹配原则
mysql 会一直向右匹配直到遇到范围查询(>,< between,like)就停止匹配,所以要讲‘='条件放在前面,吧范围查询条件放在后面
6.应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。
7.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引
8.尽量避免在where子句中对字段进行null判断,否则将导致引擎放弃索引,导致全局扫描
5、数据库优化查询效率:
1、储存引擎选择:如果数据表需要事务处理,应该考虑使用 InnoDB,因为它完全符合 ACID 特性。
如果不需要事务处理,使用默认存储引擎 MyISAM 是比较明智的
2、分表分库,主从。
3、对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索
引
4、应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全
表扫描
5、应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫
描
6、应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,
将导致引擎放弃使用索引而进行全表扫描
7、Update 语句,如果只更改 1、2 个字段,不要 Update 全部字段,否则频繁调用会引起明显的
性能消耗,同时带来大量日志
8、对于多张大数据量(这里几百条就算大了)的表 JOIN,要先分页再 JOIN,否则逻辑读会很高,
性能很差。
6、索引的好处
通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性
可以大大加快数据的检索速度,这也是创建索引的最主要的原因
可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义
在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间
7、主存的存储过程
1.当系统需要读取主存时,将地址信号放到地址总线上传给主存
2.主存读到地址信号后,解析信号并定位到指定存储单元,然后将此存储单元数据放到数据总线,供其他部件读取
8、磁盘I/O的存取
1.磁盘读取数据靠的是机械运动,当需要从磁盘读取数据时,系统会将数据逻辑地址传给磁盘
2.磁盘的控制电路按照寻址逻辑将逻辑地址翻译成物理地址,即确定要读的数据在哪个磁道,哪个扇区
3.为了读取这个扇区的数据,需要将磁头放到这个扇区上方,为了实现这一点,磁头需要移动对准相应磁道,这个过程叫做寻道
然后磁盘旋转将目标扇区旋转到磁头下,这个过程耗费的时间叫做旋转时间,最后便是对读取数据的传输。 所以每次读取数据花费的时
间可以分为寻道时间、旋转延迟、传输时间三个部分
9、redis为什么不支持回滚?
1.不需要回滚,redis内部执行更加快速
2.从实用性角度来看,错误一般是由编程错误导致,不会出现在生成环境,并且编程错误无法完全避免
10、如果有大量的key需要设置同一时间过期,一般需要注意什么?
如果大量key过期时间设置的比较集中,那么到了过期时间会使得redis出现短暂的卡顿,一般需要在过期时间上设置一个随机值,使得过期时间分散
11、持久化
bgsave做镜像全量持久化,aof做增量持久化。因为bgsave会耗费较长时间,不够实时,在停机的时候会导致大量丢失数据,所以需要aof来
配合使用。在redis实例重启时,优先使用aof来恢复内存的状态,如果没有aof日志,就会使用rdb文件来恢复。
如果再问aof文件过大恢复时间过长怎么办?
你告诉面试官,Redis会定期做aof重写,压缩aof文件日志大小。如果面试官不够满意,再拿出杀手锏答案,Redis4.0之后有了混合持久化
的功能,将bgsave的全量和aof的增量做了融合处理,这样既保证了恢复的效率又兼顾了数据的安全性。这个功能甚至很多面试官都不知道
,他们肯定会对你刮目相看。
如果对方追问那如果突然机器掉电会怎样?
取决于aof日志sync属性的配置,如果不要求性能,在每条写指令时都sync一下磁盘,就不会丢失数据。但是在高性能的要求下每次都sync
是不现实的,一般都使用定时sync,比如1s1次,这个时候最多就会丢失1s的数据。
redis有两种持久化机制RDB与AOF:
AOF:AOF机制对每条写入命令作为日志,以append-only的模式写入一个日志文件中,当redis重启的时候,可以通过回放AOF日志中的写
入指令来重新构建整个数据集
appendfsync everysec //每秒写一次硬盘,在性能和持久化方面做了很好的这种
RDB:RDB(快照)持久化机制,是对redis中数据执行周期性的持久化(将内存中的数据以快照的方式写入到二进制文件中,默认是
dump.rdb可以通过配置设置自动做快照持久化的方式。我们可以配置redis在n秒内如果m个key修改,就自动做快照)
save 900 1 #900秒内,超过1个key被修改,则发起快照保存
12、事务
multi 标记一个事务块的开始
exec 命令原子性地执行(要么都成功,要么都失败)
discard 取消事务
watch 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
unwatch 取消 WATCH 命令对所有 key 的监视。
13、Redis为什么不采用定时删除策略?
定时删除,用一个定时器来负责监视key,过期则自动删除,虽然内存及时释放,但是十分消耗资源。
在大并发的请求下,cpu要将时间应用在处理请求,而不是删除key
14、redis采用的是定期删除+惰性删除策略。
啥是惰性删除
在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除,不会给你返回任何东西
15、内存淘汰机制(# maxmemory-policy volatile-lru)
noeviction(eviction: [?'v?k?(?)n] 逐出;赶出;收回): 当内存不足以容纳新写入数据时,新写入操作会报错,这个一般没人用吧,实在是太恶心了。
allkeys-lru(Least Recently Used):当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)。
allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key,这个一般没人用吧,为啥要随机,肯定是把最近最少使用的 key 给干掉啊。
volatile-lru (volatile: ['v?l?ta?l]):当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key(这个一般不太合适)。
volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key。
volatile-ttl(Time To Live):当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。
16、单线程的redis为何这么快?
纯内存操作
单线程操作,避免了频繁的上下文切换
指的是进程或线程从CPU切换到另一个进程或线程
采用了非阻塞I/O多路复用机制:我们的redis-client在操作的时候,会产生具有不同事件类型的socket。在服务端,有一段I/0多路复用程序,将其置入队列之中。然后,文件事件分派器,依次去队列中取,转发到不同的事件处理器中
17、Redis的同步机制了解么?
前言
在redis中用户可以通过执行SLAVEOF命令或者slaveof选项,让一个服务器去复制另外一个服务器,我们称被复制的服务器为主服务器(master),而对主服务器复制的服务器称为从服务器(slave)
同步步骤
1. 从服务器向主服务器发送SYNC命令。
2. 收到SYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令。
3. 当主服务器的BGSAVE命令执行完毕时,主服务器会将BGSAVE命令生成的RDB文件发送给从服务器,从服务器接收并载人这个RDB文件
,将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态。
4.主服务器将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当
前所处的状态
18、使用过Redis做异步队列么,你是怎么用的?
一般使用list结构作为队列,rpush生产消息,lpop消费消息,当Lpop没有消息的时候,