针对循环查询的逻辑优化思路

在工作中总能碰见有人的接口使用循环查询数据库的情况,针对这种情况我总结了一些针对这种情况的初步优化思路. 限制和优点 限制 此种方法只针对循环查询这种类型的优化 优点 不用完全了解业务逻辑,即可完成有效的优化 方法 概述 先明确循环的位置, 以及循环内要查的数据 采用包一层的思路(计算机界没有什么是包一层不能解决的, 如果不能就再包一层😊), 把查询提前到循环外, 通过提供相同的查询逻辑(在内存里的查询),替换循环中的查询(数据库的查询),必须保证新的查询和老查询功能一致. 听起来好像没什么特别的,我们来看下具体实施过程 伪代码 假设有一个这种函数 func GetPersonList(xx) { ps := models.GetPersonByXX() for _, v := range ps { //xxxx很多逻辑,很复杂 orders := models.GetOrderByPerson(v.ID) //这里循环查数据库,我们需要看懂这块的查询条件和返回值 //xxx很多逻辑,很复杂 } } 我们可以这样优化 //1. 在models层实现一个批量查询接口 models.GetOrderByPersons(id ...int) //2. 包一层实现一个数据缓存结构 type OrderDataCache struct { order map[int/*person id */] []Order //这里的结构根据具体查询定义, 上述例子是通过person id查 } //3. 初始化数据缓存结构函数, 根据你具体的业务实现 func NewOrderDataCache(personID ....int) OrderDataCache { //调用批量查询 orders := models.GetOrderByPersons(id ...int) for _, v := range orders { //处理成[personid] []Order 结构 } return OrderDataCache{ //[personid] []Order } } //4. 用来替换循环查询的方法, 和单次查询的查询条件和返回值保持一致 func (o OrderDataCache) GetOrderByPerson( persionID int) []Order { //这里实现一个和orders := models.GetOrderByPerson(v.ID) 一样的查询逻辑 return o.order[persionID] } func GetPersonList(xx) { ps := models.GetPersonByXX() orderCache := NewOrderDataCache(ps中提取id) //6.批量查询 for _, v := range ps { //xxxx很多逻辑,很复杂 orders := orderCache.GetOrderByPerson(v.ID) //7. 查询替换成我们新的方法 //xxx很多逻辑,很复杂 } }

<span title='2023-02-02 17:06:48 +0800 +0800'>二月 2, 2023</span>