提升Ruby网站性能的秘诀:只需多写一句代码

发表时间: 2017-11-03 07:30

最近在用RubyOnRails写一个学校用的客户关系管理系统,生产环境用的是Ubuntu Linux,打开后台看系统日志的时候,发现数据读取消耗资源异常大,仔细查找每一条语句,原来sql语句没有做优化,一旦有关联的查询,都会嵌套遍历,也就是常说的N+1查询问题。


源起

举个例子,两个Model,Post和Comment的对应关系是一对多

执行语句,看一下后台输出结果

会发现在查询到一条post后,会遍历对应的关系数据,一共执行了5(4+1)次查询,这就是N+1查询问题所在


解决

预加载,简单说就是提前加载需要的数据,Rails提供了三种加载方式

  • includes

  • preload

  • eager_load

我们用比较常用的includes试试效果

后台数据查询仅执行了两次,这种问题在数据记录多的情况下尤其显明。性能问题完美解决


区别

既然有三种方式解决问题,他们的区别在哪?

preload,这也是includes默认的加载方式

它总会生成两条语句,并且它有个问题,不能在where中使用post表,比如下面的查询就不可以

注意这段数据库会报错

eager_load,默认使用了左外链接的方式查数据

includes,更加智能,它可以自动判断应该用哪种方式,初学者可以直接用includes,而不必管其它的两种方式