持久层
- 注:持久层数据库以postgresql为例
使用索引
- 索引主要是对于查询业务比较有帮助,根据业务逻辑对要查询的某个字段或多个字段加索引,可以极大提升查询速度,几十倍到几百倍
创建索引
- postgresql创建组合索引的语法如下:
create index index_name on table_name(field_name1, field_name2, ···);
- 如:
create index teacher_id_type_deletion_flag on assess(teacher_id, type, deletion_flag);
避免索引失效
- 参考:sql优化指南
分析索引使用情况
- 就拿上文创建的索引来说,语法如下:
explain ANALYZE select * from assess where teacher_id = 680 and type = 1 and deletion_flag = 0;
- 具体分析参考:https://blog.csdn.net/qq_26373925/article/details/110453507
- 使用索引至少要符合最左前缀匹配原则,索引才可能生效
查看索引
\di
查看当前数据库所有索引select * from pg_stat_all_indexes;
查看索引使用情况、状态(好像也是当前数据库)
字段解释:relid oid
索引的表的OIDindexrelid oid
索引的OIDschemaname name
索引中模式名relname name
索引的表名indexrelname name
索引名idx_scan bigint
索引上开始的索引扫描数idx_tup_read bigint
通过索引上扫描返回的索引项数idx_tup_fetch bigint
通过使用索引的简单索引扫描抓取的活表行数
删除索引
drop index index_name
如果有scheme可能还要用drop index scheme_name.index_name
缓存层
什么数据放缓存
- 不经常改变的数据
- 数据变化非常快,且接口的查询速度稍慢(几秒钟),但正好实时性要求不是特别高
缓存更新策略
- 以下的策略与上文放入缓存的数据一一对应:
- 在数据变化时更新
- 可以几分钟更新一次,接口的查询速度在几秒钟左右最适合这种策略(
如果超过5s,其实用户体验就很不好了,业务逻辑不能再优化的情况下,那只能放缓存了
)
应用层
- 应用层要尽量减少调用数据库,不要在多层嵌套for循环的最内层请求数据库
- 对象的声明放在循环外面
- 尽量降低代码的时间复杂度
- 对于一些特殊的情况,可以使用异步任务
限流策略
参考:
服务器
网络带宽
- 事先预估带宽峰值
系统平均负载
- 参考:Linux的平均负载
其他策略
- 关闭一些无关紧要的服务,释放更多资源供当前服务使用,一个Java服务可能会占据几百MB内存甚至更多
- 生产环境中,日志级别升为
Info
- 物理删除数据库中已经被逻辑删除的数据,即
deletion_flag = 1
的数据
性能测试
参考: