beego web提高后端速度的尝试——改循环查询数据库为递归算法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hotqin888/article/details/80530311

最开始对付项目列表中的每个项目的成果数量,采用查询数据库,循环去查,因为一个项目下面有4~6层目录,每一层为几十个目录,这样一个项目下大概有4800个目录,每个目录下有成百上千的成果。

这样一个树状项目目录表category,

id parentid

和对应的成果表product。

id categoryid

试了一下,30个项目情况下,成果数量为0,仅项目列表显示要花2s。

页面中的项目列表要反应每个项目下的成果。如果成百上千个项目,然后每个项目下4800个目录,要查询每个目录下的成果数量……

因为:要么循环查询数据库,要么把所有项目目录category表一次性查出来(15.6万),把所有成果product表一次性查出来(beego orm默认只会查出1000个结果来),再循环——递归。

func (c *ProjController) GetProjects() {
	id := c.Ctx.Input.Param(":id")
	if id == "" {
		//显示全部
		projects, err := models.GetProjects()
		if err != nil {
			beego.Error(err)
		}
		categories, err := models.GetAllProjects()
		if err != nil {
			beego.Error(err)
		}
		products, err := models.GetAllProducts()
		if err != nil {
			beego.Error(err)
		}
		//取得每个项目的成果数量
		projects1 := make([]Project1, 0) //这里不能加*号
		for _, v := range projects {
			aa := make([]Project1, 1)
			aa[0].Id = v.Id
			aa[0].Code = v.Code
			aa[0].Title = v.Title
			aa[0].Label = v.Label
			aa[0].Principal = v.Principal
			//取得项目所有成果——速度太慢
			//修改为一次性取到所有成过,然后循环赋值给aa
			//取项目本身
			// category, err := models.GetProj(v.Id)
			// if err != nil {
			// 	beego.Error(err)
			// }
			//取项目所有子孙——这样效率太低
			// categories, err := models.GetProjectsbyPid(v.Id)
			// if err != nil {
			// 	beego.Error(err)
			// }
			//根据项目id取得项目下所有成果
			//——效率太低
			// products, err := models.GetProjProducts(v.Id)
			// if err != nil {
			// 	beego.Error(err)
			// }
			var count int
			for _, m := range products {
				if v.Id == m.ProjectId {
					count = count + 1
				}
			}
			slice := getsons(v.Id, categories)
			// 如果遍历的当前节点下还有子节点,则进入该子节点进行递归
			if len(slice) > 0 {
				getprodcount(slice, categories, products, &count)
			}
			aa[0].Number = count //len(products)
			aa[0].Created = v.Created
			aa[0].Updated = v.Updated
			projects1 = append(projects1, aa...)
		}
		c.Data["json"] = projects1
		c.ServeJSON()
	} else {
		//根据标签查询
	}
}

改进:

将数据库目录表category增加一个字段,每个项目的子目录都带有这个项目的id,这样一次性查出这个项目的所有目录(相当于加了一个索引)。

id parentid projectid

再改进一下成果表,将成果表增加一个字段,除了目录id外,增加一个项目id,这样一次性查出这个项目的所有成果和成果数量(相当于加了一个索引)。

id categoryid projectid

接下来,就是树状目录显示成果数量的问题了,每个子目录都要显示这个目录下所有成果数量。

树状目录采用懒加载,一次只加载一层。但是这一层还是要计算出所有下级成果数量。还是采用递归。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Golang语言社区

Go的单元测试技巧

本文为社区粉丝原创投稿,再次感谢作者DrmagicE的分享,欢迎大家在评论区留言和作者讨论,同时也欢迎大家踊跃投稿,分享您的golang语言学习经验!投稿邮箱地...

1303
来自专栏杨建荣的学习笔记

关于分区表的move操作(r2笔记90天)

关于分区表的move操作还是很值得深究的一个问题。如果分区表中含有lob字段,难度还会加大。 对于普通的表而言,做move操作室理所当然,oracle提供的方...

3465
来自专栏C#

NodeJS异步I/O解析

    在现在的项目开发中,任何一个大型项目绝对不是简简单单的采用一个种语言和一种框架,因为每种语言和框架各有优势,与其死守一个,不与取各家之所长,依次得到一个...

2909
来自专栏张戈的专栏

WordPress发布文章主动推送到百度,加快收录保护原创

工作实在太忙,也没时间打理网站。最近公司额外交待了一些网站 SEO 方面的优化任务让我关注(这就是啥都要会、啥都要做的苦逼运维的真实写照了...)。 于是抽空看...

3486
来自专栏程序员互动联盟

【盟友分享】如何快速获取Chromium源码和编译

感谢盟友:我为之狂的热心分享!同时也希望盟友们多多分享自己写的不错的文章哦; 正文: 最近准备研究下Chromium源码,但在获取Chromium源码以及编译...

6578
来自专栏Web 开发

小项目里面的大内涵

额~因为我从没系统的看过,所以实施的时候总是出这样那样的语法问题,尤其是对 ‘ “ . ` 这些个符号的使用,非常混乱~

983
来自专栏崔庆才的专栏

为什么分布式一定要有redis?

2843
来自专栏QQ音乐技术团队的专栏

如何设计一个可靠的消息系统

全民K歌的消息包含两种:一种是用户作品相关的消息汇聚,用户所有作品的评论、送礼等,按照时间线纵向给用户聚合起来。一种是横向用户与用户之间的交流信息,提供类似QQ...

29810
来自专栏Linuxer的专栏

谢宝友: 深入理解 Linux RCU 之从硬件说起

想要制造出质量可靠的桥梁,就必须真正懂得力学原理。对于想要理解RCU的软件工程师来说,也需要具备一定的硬件基础。

1K0
来自专栏pangguoming

使用JAVA开发微信公众平台(一)——环境搭建与开发接入

一、 初始微信公众平台 微信公众平台,即我们平时所说的“公众号”,曾用名“官方平台”、“媒体平台”,但最终命名为“公众平台”。从微信的命名我可以发现,公众平台不...

6046

扫码关注云+社区

领取腾讯云代金券