1.索引优化的时候要注意啥?
1、索引字段要尽可能少的占用存储空间
2、在满足业务系统的需求内尽可能自增
3、索引字段尽可能不要为null
4、选择索引的时候索引的基数要尽可能的大Dv(distinct value)/count> =80%的字段适合创建索引
5、不要给所有的字段都添加索引,并不是索引越多越好
6、尽量避免索引失效
7、索引字段尽量不要频繁修改
2.索引失效的10种场景
1.不满足最左匹配原则
2.使用了select *
3.索引列上有计算
4.索引列用了函数
5.字段类型不同
6.like左边包含%
7.列对比
8.使用or关键字
9.not in 和 not exists
10.order by 的坑
3.回表
id, name, age,gender四个字段
id是主键,name是普通索引
select * from table where name='zhangsan";
查找过程:先根据name的值去name B+树找到对应的叶子节点,取出id值,再根据id值去id B+树中查找全部的结果,这个过程称之为回表
回表的效率比较低,尽可能避免回表的产生
4.索引覆盖
id, name, age,gender四个字段
id是主键,name是普通索引
select id, name from table where name='zhangsan";
查找过程:先根据name的值去name的B+树查找结果,能够直接获取到id和name,不需要去id的B+树查到数据了,这个过利叫做索引覆盖
索引的叶子节点中包含了要查询的全部数据,叫做索引覆盖
5.索引下推
id, name,age, gender
id是主键,name,age是组合索引,在查询的时候必须要从左向右匹配
select * from table where name=? and age= ?;
没有索引下推之前:先根据name的值从存储引擎中拿到符合条件的数据,然后在server中对age进行数据过滤
有了索引下推之后:直接根据name和age从存储引擎中筛选对应的数据,返回给server,不需要做数据过滤
缓存穿透&缓存击穿&缓存雪崩
缓存穿透
描述:访问一个缓存和数据库都不存在的 key,此时会直接打到数据库上,并且查不到数据,没法写缓存,所以下一次同样会打到数据库上。
此时,缓存起不到作用,请求每次都会走到数据库,流量大时数据库可能会被打挂。此时缓存就好像被“穿透”了一样,起不到任何作用。
解决方案:缓存空值。当访问缓存和DB都没有查询到值时,可以将空值写进缓存,但是设置较短的过期时间,该时间需要根据产品业务特性来设置。
缓存击穿
描述:某一个热点 key,在缓存过期的一瞬间,同时有大量的请求打进来,由于此时缓存过期了,所以请求最终都会走到数据库,造成瞬时数据库请求量大、压力骤增,甚至可能打垮数据库。
解决方案:热点数据不过期。直接将缓存设置为不过期,然后由定时任务去异步加载数据,更新缓存。这种方式适用于比较极端的场景,例如流量特别特别大的场景,使用时需要考虑业务能接受数据不一致的时间,还有就是异常情况的处理,不要到时候缓存刷新不上,一直是脏数据,那就凉了。
缓存雪崩
描述:大量的热点 key 设置了相同的过期时间,导在缓存在同一时刻全部失效,造成瞬时数据库请求量大、压力骤增,引起雪崩,甚至导致数据库被打挂。
缓存雪崩其实有点像“升级版的缓存击穿”,缓存击穿是一个热点 key,缓存雪崩是一组热点 key。
解决方案:热点数据不过期。该方式和缓存击穿一样,也是要着重考虑刷新的时间间隔和数据异常如何处理的情况。