欢迎光临Software MyZone,有问题可留言或到站点论坛发帖,争取第一时间帮忙解决 || 站点论坛:火龙论坛 || 淘宝小店:应小心的易淘屋 【欢迎大家提建设性意见】

Rails应用性能优化(四)–self

数据库优化:
1)模板引擎的选择:http://www.phpq.net/mysql/myisam-innodb.html
(1)MyISAM(B树磁盘表):查询速度快,强调了快速读取操作,这可能就是为什么MySQL受到了Web开发如此青睐的主 要原因:在Web开发中你所进行的大量数据操作都是读取操作。所以,大多数虚拟主机提供商和Internet平台提供商(Internet Presence Provider,IPP)只允许使用MyISAM格式。但是不支持事务处理也不支持外来键
(2)INNODB:包括了对事务处理和外来键的支持,但是比MyISAM引擎慢很多
2)参数配置:my.ini(linux-my.cnf)
(1) innodb_flush_log_at_trx_commit=2
#抱怨Innodb比MyISAM慢 100倍?那么你大概是忘了调整这个值。默认值1的意思是每一次事务提交或事务外的指令都需要把日志写入(flush)硬盘,这是很费时的。特别是使用电 池供电缓存(Battery backed up cache)时。设成2对于很多运用,特别是从MyISAM表转过来的是可以的,它的意思是不写入硬盘而是写入系统缓存。日志仍然会每秒flush到硬 盘,所以你一般不会丢失超过1-2秒的更新。设成0会更快一点,但安全方面比较差,即使MySQL挂了也可能会丢失事务的数据。而值2只会在整个操作系统 挂了时才可能丢数据。
#MySQL 5.0里面,MyISAM和InnoDB存储引擎性能差别并不是很大,针对InnoDB来说,影响性能的主要是 innodb_flush_log_at_trx_commit 这个选项,如果设置为1的话,那么每次插入数据的时候都会自动提交,导致性能急剧下降,应该是跟刷新日志有关系,设置为0效率能够看到明显提升
(2)key_buffer_size 24M
#这对MyISAM表来说非常重要。如果只是使用MyISAM表,可以把它设置为可用内存的 30-40%。合理的值取决于索引大小、数据量以及负载 — 记住,MyISAM表会使用操作系统的缓存来缓存数据,因此需要留出部分内存给它们,很多情况下数据比索引大多了。尽管如此,需要总是检查是否所有的 key_buffer 都被利用了 — .MYI 文件只有 1GB,而 key_buffer 却设置为 4GB 的情况是非常少的。这么做太浪费了。如果你很少使用MyISAM表,那么也保留低于 16-32MB 的key_buffer_size 以适应给予磁盘的临时表索引所需。
(3)table_cache
#table_cache指定表高速缓存的大小。每当MySQL访问一个表时,如果在表缓冲区中还有空间,该表就被打开并放入其中,这样可以更快地访问表内容。通过检查峰值时间的状态值Open_tables和Opened_tables,可以决定是否需要增加table_cache的值。如果你发现open_tables等于table_cache,并且opened_tables在不断增长,那么你就需要增加table_cache的值了(上述状态值可以使用SHOW STATUS LIKE ‘Open%tables’获得)。注意,不能盲目地把table_cache设置成很大的值。如果设置得太高,可能会造成文件描述符不足,从而造成性能不稳定或者连接失败。 对于有1G内存的机器,推荐值是128-256。 笔者设置table_cache = 256
(4)skip-name-resolve
#禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间。但需要注意,如果开启该选项,则所有远程主机连接授权都要使用IP地址方式,否则MySQL将无法正常处理连接请求!注:如果用winform连接mysql,加入此句速度会有很大的提升
(5)innodb_buffer_pool_size = 1G
#这对Innodb表来说非常重要。Innodb相比MyISAM表对缓冲更为敏感。MyISAM可以在默认的 key_buffer_size 设置下运行的可以,然而Innodb在默认的innodb_buffer_pool_size 设置下却跟蜗牛似的。由于Innodb把数据和索引都缓存起来,无需留给操作系统太多的内存,因此如果只需要用Innodb的话则可以设置它高达 70-80% 的可用内存。– 如果你的数据量不大,并且不会暴增,那么无需把innodb_buffer_pool_size 设置的太大了。
(6)query_cache_size
#当在使用中,查询缓存会存储一个 SELECT 查询的文本与被传送到客户端的相应结果。如果之后接收到一个同样的查询,服务器将从查询缓存中检索,注意:查询缓存绝不返回过期数据。当数据被修改后,在查询缓存中的任何相关词条均被转储清除。在某些表并不经常更改,而你又对它执行大量的相同查询时,查询缓存将是非常有用的。对于许多 WEB 服务器使用大量的动态信息,这是一个很典型的情况。
(7)innodb_flush_method
#从上面的对比可以看出,单纯从写入的角度讲,默认的fdatasync性能最佳,其次是O_DSYNC,最差的是O_DIRECT。

 

应用优化:
1) 尽可能少访问数据库,views层定义变量,最好释放变量,减少递归查询,减少业务逻辑处理(路由,多个页面),hash的key使用symbol
2)js的加载
3)控制器的精简,数据库的查询
4)路由的except
5)数据库
(a)原生态sql
(b)find_each
(c)设计关联的使用include,处理好n+1问题
解释:N+1 查询问题
(1)N+1 查询问题–立即加载 一层嵌套:查询添加 Post.find(:all, :include=>[:category]) <%=p.category.name%>
(2) N+1 查询问题–嵌套的立即加载 两层嵌套:查询添加 Post.find(:all, :include=>{ :category=>[],:author=>{ :image=>[]}} ) <%=p.category.name%><%=image_tag p.author.image.public_filename %>
(3) N+1 查询问题–间接的立即加载 查询添加 User.find(5, :include=>{:posts=>[:user]})

<%@user = User.find(5)
@user.posts.each do |p|%>
<%=render :partial=>’posts/summary’, :locals=>:post=>p
%> <%end%>
当然,决定查询的数量需要对 posts/summary partial 有所了解。清单 8 中显示了这个 partial。
清单 8. 间接立即加载 partial: posts/_summary.html.erb
<h1><%=post.user.name%></h1>
grep “200 OK” production.log | awk ‘{print “ALL: ” $3 ” View: ” $8 ” DB: ” $12 ” URL: ” $17 }’ | sort -r | head -n 500 > timing.log

发表评论