树,morphia,查询,优化和擦屁股!

2012年 一月 13日 周五 | tags: java, morphia, mongo, code, -- (permalink)

前天和昨天一直都在忙后台CMS树的优化和一些bug的修改,不过主要精力放在了树的优化上。

后台数据较多的树有两个,都是和视频相 关的,我们的树用的是dwz的树,但是这是一个同步树,也就是说,这个树是一次性取出数据,通过freemarker构建成html代码,然后在由dwz 渲染成树,在数据量小的时候还不觉得有什么,但是数据量一大就会发现,后台服务端数据查询还不用什么,但是dwz渲染那是一个慢啊,后来我一个同事找了个 jquery的一个异步树,然后由我来对树进行更换。

在换掉dwz的树之后发现,虽然加载数据的速度提升很大,但是在某些数据量略大的节点上依然会有查询很慢的问题,长一点的有要到7-8秒的时间。这样长的时间主要是因为3个方面:

  1. 第一个就是dwz的树是同步树,在接收完数据之后,才进行树的渲染,在数据量略微大的话,渲染的效率就很低,而且我们的树是5级的,五层循环下来,基本上要循环过百万次,在firefox和chrome下测试发现,虽然chrome的js渲染速度快,但是效果并不明显
  2. 第二个就是mongodb的问题,但是问题不在与mongodb上,而在于我们的查询上,几个树加载慢的表都冗余了大量的数据,这些数据在树的显示上都没有用,一个树需要的只有一个id和name两个字段,所以在查询上带出了太多的无用数据。
  3. 第三个就是在网络传输上,这个问题其实和第二个是一样的,从mongodb带出了太多的无用数据,而且是一次性全部数据都查寻来,这样就会造成数据越多查询越慢,网络的传输上压力就越大,到最后就是服务器崩掉

解 决这问题其实很简单,对症下药而已,dwz是同步树,那就换成异步树,每次只加载点击节点下的数据,mongodb查询带出了大量无用的冗余数据,但是我 们只用了id和name那就在查询的时候只查出id和name,morphia的Query有个方法retrievedFields方法(参数的说明请参看API文档或者源代码),这个方法可以查询的时候只抓取想要的字段,这样不但可以减少在mongodb查询时间,同时也减小了网络传输的时间。

我 现在无法给出具体的时间数据,因为我手上没有未优化的代码,但是在优化之前我清楚的记得,生成一次树的时间是几十秒甚至几分钟,加了异步树之后每次只加载 当前点击的节点,所以体验上好了很多,但是在打开节点下的时候,因为数据量有点大(大概有1k行的样子),虽然看着不多,但是这个表冗余了很多数据,说是 一千行,但是实际的数据可能会多几十倍,甚至过百倍,所以在只抓取id和name的时候,数据提升了很大,从8-15秒提升到了40-80ms,当然这里 面数值下线都是在chrome中测试的结果,在这里不得不在此赞叹一下V8引擎,真的是太TMD的快了。

在最后的吐槽中,我实在是想骂娘,这代码是谁写的,让哥抗了一天没吃饭,一直到下午6点才做完去吃饭,饿死哥了!