写点什么

提高 Ruby on Rails 性能的几种技巧

  • 2010-08-18
  • 本文字数:1332 字

    阅读完需:约 4 分钟

Ruby on Rails 以其高度的易用性和灵活性著称,不过这些优点的背后还存在着性能的隐患。最近,资深 Ruby on Rails 作家 David Berube 提供了几个 Ruby on Rails 性能优化的技巧,对相关开发人员具有一定的借鉴意义。

David Berube 在文章中首先分析了 Rails 应用运行缓慢的原因:

  • Rails 总是会做一些假设为您加速开发。通常,这种假设是正确而有帮助的。不过,它们并不总能有益于性能,并且还会导致资源使用的效率低下——尤其是数据库资源。
  • 另一个显著的挑战是 N+1 问题…这会导致很多小查询的执行,而不是一个单一的大查询。例如,ActiveRecord 无从知道一组父记录中的哪一个会请求一个子记录,所以它会为每个父记录生成一个子记录查询。由于每查询的负荷,这种行为将导致明显的性能问题。
  • 由于 ActiveRecord 能够让如此众多的任务变得轻而易举,Rails 开发人员常常会形成 “SQL 不怎样” 的一种态度,即便在更适合使用 SQL 的时候,也会避免 SQL。创建和处理数量巨大的 ActiveRecord 对象的速度会非常缓慢,所以在有些情况下,直接编写一个无需实例化任何对象的 SQL 查询会更快些。

对于如何检测性能问题, David Berube 提供了一些建议:

  • 最好的工具之一是 Rails 开发日志,它通常位于每个开发机器上的 log/development.log 文件内。它具有各种综合指标:响应请求所花费的总时间、花费在数据库内的时间所占的百分比、生成视图所花时间的百分比等。
  • 在生产期间,通过查看 mysql_slow_log 可以找到很多有价值的信息。
  • 其中一个最强大也是最为有用的工具是 query_reviewer 插件。这个插件可显示在页面上有多少查询在执行以及页面生成需要多长时间。并且它还会自动分析 ActiveRecord 生成的 SQL 代码以便发现潜在问题。例如,它能找到不使用 MySQL 索引的查询,所以如果您忘记了索引一个重要的列并由此造成了性能问题,那么您将能很容易地找到这个列。此插件在一个弹出的
    (只在开发模式下可见)中显示了所有这类信息。

针对 N+1 查询问题,David Berube 举了一个未优化的代码示例:

<%@posts = Post.all(@posts).each do |p|%>

<%=p.category.name%>

<%=p.body%>

<%end%>

David Berube 指出,上述代码生成了一个查询外加 @posts 内的每行一个查询。由于每查询的负荷,这可能会成为一个很大的挑战。罪魁祸首是对 p.category.name 的调用。这个调用只应用于该特定的 post 对象,而不是整个 @posts 数组。这种情况通过使用立即加载可以修复。立即加载(Eager loading)意味着 Rails 将自动执行所需的查询来加载任何特定子对象的对象。Rails 将使用一个 JOIN SQL 语句或一个执行多个查询的策略。不过,假设指定了将要使用的所有子对象,那么将永远不会导致 N+1 的情形,在 N+1 情形下,一个循环的每个迭代都会生成额外的一个查询。优化后的代码如下:

<%@posts = Post.find(:all, :include=>[:category] @posts.each do |p|%>

<%=p.category.name%>

<%=p.body%>

<%end%>

比较复杂的情况包括嵌套的立即加载间接的立即加载

除了解决 N+1 问题之外,David Berube 还提供了其他一些优化建议:

InfoQ 将继续关注 Ruby on Rails 的发展,读者朋友可以通过 InfoQ 中文站 Ruby 社区了解更多信息。

2010-08-18 23:563758
用户头像

发布了 501 篇内容, 共 280.7 次阅读, 收获喜欢 64 次。

关注

评论

发布
暂无评论
发现更多内容

淘宝商品关键词API接口:智能分析关键词数据,提升电商运营效率

代码忍者

API 接口 pinduoduo API

第74期 | GPTSecurity周报

云起无垠

南京大学 鲲鹏昇腾科教创新孵化中心揭牌,引领高校科研生态新模式

极客天地

【问卷调研】HarmonyOS SDK开发者社区用户需求有奖调研

HarmonyOS SDK

操作系统大会2024即将在京召开,见证openEuler发展新里程

科技热闻

哇喔!20种单例模式的实现与变异总结

威哥爱编程

Java 设计模式 单例模式 JavaEE

覆盖30个省市自治区万余家医疗机构,原生鸿蒙助力打造智慧医疗便利体验

最新动态

大选获胜,盘点特朗普相关加密货币资产

TechubNews

GitLab 如何降级安装?

极狐GitLab

Serverless 微服务治理神器: 阿里云 SAE 全链路灰度揭秘

阿里巴巴云原生

阿里云 Serverless 云原生

【JIT/极态云】技术文档--模型事件

武汉万云网络科技有限公司

【JIT/极态云】技术文档--审批事件

武汉万云网络科技有限公司

怎么在线画用户旅程图?分享10个用户旅程图模板!

职场工具箱

职场 产品经理 在线白板 绘图工具 用户旅程图

2024年AI办公工具API:优化工作流程的智能解决方案

幂简集成

API

MES系统助力中小企业数字化转型

万界星空科技

数字化转型 生产管理系统 mes 万界星空科技 中小企业数字化转型

淘宝订单信息获取接口,淘宝订单信息获取API

tbapi

淘宝API接口 淘宝店铺订单接口 天猫店铺订单接口 淘宝店铺订单API

如何使用PHP开发API接口?

科普小能手

php API php扩展 API接口 API 测试

《实力见证,卓越前行 ——伊克罗德信息荣获 Amazon Redshift Delivery 认证》

伊克罗德信息科技

大数据 Amazon

尝鲜智能体,今年双十一“快递100”用上混元大模型

极客天地

Python 如何根据给定模型计算权值

不在线第一只蜗牛

Python 深度学习

GitLab 出现 500错误怎么解决?

极狐GitLab

gitlab

AI时代的研发生产关系,是否有新的可能?

思码逸研发效能

快递鸟单号识别API接口代码操作流程

快递鸟

快递

2024-11-13:求出所有子序列的能量和。用go语言,给定一个整数数组nums和一个正整数k, 定义一个子序列的能量为子序列中任意两个元素之间的差值绝对值的最小值。 找出nums中长度为k的所有子

福大大架构师每日一题

福大大架构师每日一题

5分钟搞懂 Golang 数据库连接管理

俞凡

golang

鸿蒙网络编程系列47-仓颉版UDP客户端

长弓三石

DevEco Studio 开发实例 HarmonyOS NEXT 网络与连接

公链数字钱包开发与加密钱包App原生开发

区块链软件开发推广运营

交易所开发 dapp开发 链游开发 公链开发 代币开发

区块链NFT项目开发流程

区块链软件开发推广运营

交易所开发 dapp开发 链游开发 公链开发 代币开发

提高Ruby on Rails性能的几种技巧_Ruby_崔康_InfoQ精选文章