事关生死存亡,性能提升14倍!一次Python Web项目的性能优化

2020-06-29 15:48:38 浏览数 (1)

熟悉我的读者应该都知道,州的先生最近开源了一个使用 Python 编写的 Markdown 在线文档系统——MrDoc觅道文档

一、事出有因

昨天发布了一个新的版本,主要解决了一个被网络上某网友称之为“重大 Bug 问题”的性能问题。

(某网友在其博客上发布的文章)

据其称:

把数据库加载到20M的时候,页面加载缓慢问题非常明显了,数据条数没多少,但每一条有3000字左右的汉字,因为Content字段和Pre_content字段内容一致问题,Sqlite3数据文件大小增大了一倍左右。

看到这篇文章之后,第一时间想找到这个博主,让其提供详细的详细,方便复现 Bug 和调试。后来一看这个博客名称有点眼熟,原来他在“MrDoc交流QQ群”中,于是便打算问他一下:

没成想,他竟然退群了……退群……群了……了。

没办法,索要测试文件无果,虽然知道有此 Bug 的存在,但是没有实际的样例来测试,只得暂时作罢。

二、一线转机

后来,事情出现了转机……

群内一个朋友拿 MrDoc 当小说站来用,在网上爬了一部小说到 MrDoc 的Sqlite 数据库里。

嗯,4千多章的小说:

把 sqlite 文件的大小写入到了 32MB。

启动 MrDoc,打开首页正常。

打开文集页,响应完成需要 56 秒,近乎挂掉了:

借着这位朋友提供的 sqlite 文件,开始了定位问题点之旅。

三、找出元凶

首页打开是没问题的,但是打开文集页就响应巨慢,然后打开文档页也会响应巨慢。那么就先从文集页的代码审查起。

文集页面后端视图函数代码主要有两块涉及到数据库的查询:

  1. 查询文集的信息
  2. 查询文集的一级文档的信息

经过调试发现,这两块的数据库查询都是很快就完成了的。说明问题不出现在这里。

回想起文集页面的目录大纲使用了 Django 的自定义模板过滤器来获取文档的下一级文档

在自定义的模板过滤器中又调用了数据库的查询:

继续在这里调试,发现问题果然出在这里。

文集有 4230 个一级文档,自定义的模板过滤器代码会查询这 4230 个文档每一个文档是否存在下级文档,这时间消耗算起来,也就是网页响应上消耗的那 50 几秒了。

四、极速处理

找到问题的所在,那就好办了。

首先,问题出在数据库的查询上,在不改动现有数据库结构的前提下提高数据库的查询效率,第一个想到的是添加索引

索引添加之后,查询效率是会提高很多。但是在之前的文集文档页面中,文集的目录大纲和文集文档内容是一起在后端渲染(包含模板渲染)的。

考虑到体验的友好性,将文集目录大纲的生成改为了前端请求后端接口数据然后再进行渲染解析

最终,将网页加载时间缩减至2秒,网页响应完成时间缩减至4秒:

相比较之前 4230 篇文档加载56秒的结果来看,在此测试 sqlite 数据库文件下,性能提升了 14 倍。

当然,对于 Web 应用性能的优化,还有很长的路要走。因时、按需、恰当地进行性能优化,也是 MrDoc 未来更新和迭代的一个重点方向,毕竟,MrDoc 的目标,不只是一个 Demo 和残废。

0 人点赞