别笑!我也加入了标题党 ,本来也算不上是什么受限环境嘛,就是共享的主机,国内的不说了,国外的哪个主机商现在都支持rails了, 看着不管HostMonster, GoDaddy 还是 LunarPages ,每月6、7美元, 几百个G的存储容量 ,每月上千G的带宽,看着都流口水。。。,不弄几个程序扔上去 , 都觉得对不起他们。
谁让咱们是程序员呢,自己写吧, 别用WordPress/PHP Board之类现成的了, 谁让现在 Rails 热呢, 咱也来趟趟这浑水。写啥?这个你就别问了, 想写啥写啥吧。没的可写?那咱们就有共同语言了,我也没有什么创意呀。 ,没有创意那就抄吧。这个也不会 ?那您就别当程序员了,哈哈 。抄啥呢 ?google ? 搜索算法也没学呢。 抄淘宝?估计马云就是你迈不过去的坎,突然发现了digg , 就是他了,发现用rails 抄digg简直是绝配,digg不是要投票吗?acts_as_voteable可以。digg不是要评论吗?acts_as_commentable 就行。Digg不是要标签吗?acts_as_taggable_on_steroids 来喽。再加上登录 restful_authentication , 分页插件 will_paginate ,不需要自己写啥,一个digg 不就出来了吗 :)
仔细看看digg , 发现这个家伙计算量还真不小,首先页面上每个帖子都是发布在几分钟之前,这个就不好缓存了吧 ? 估计是算出来得。然后 还计算你是否投了票, 居然还要看看这个帖子是不是你好友发的。。。唉,难道web 2.0 都这样?
要知道在共享主机上是没有mem cache 用的,每个数据都是直接在db(mysql) 里面读,Rails 最常用的 缓存 cache_fu 就没用喽。来来来, 算算我的程序需要多少次读,在没有:include => [:xxx] 的情况下 , 首页 要显示 10 个帖子 ,每个帖子要有个用户, 每个帖子还有 标签 ,还有投票数量 还有 评论数量 还有一个封面图片 , 开始算:
显示 10 个帖子 1 个查询 select * from xxxs limits => 10
用户 10个查询 select * form user where user_id = xxx
标签 10 个 具体怎么算 是acts_as_taggable_on_steroids干的,也是比较复杂
投票数量 10 个 count(*)
评论数量 也是10 个 count(*)
封面图片 10 个 select
总共 1 + 10 + 10 + 10 + 10 + 10 = 51个查询 呀
天哪 , 那台几百人用的共享主机怎么受得了?开始优化吧!
看到 acts_as_taggable_on_steroids 有缓存标签的功能 , 就是把主表增加一个字段cached_tag_list 每次读 tag 的时候,读这个字段就可以了。功能加上了 , 现在变成41个查询了。
联想到投票和评论, 咱也学学人家acts_as_taggable_on_steroids 把它们改成缓存吧 。主表加了2个字段cached_votes_count , cached_comments_count ,改了改acts_as_voteable和acts_as_commentable ,终于把这2个数字也缓存了 ,顺便说一下 voteabl/ commentable 这2个插件是同一个大哥写的, 写的还不是一般二般的烂, 你跟人家写taggable的大哥比比 , 怎么就这么不用心呢?还得让我2次加工,不知道我用这些插件就是为了偷懒的吗 :)接着表扬一下写taggable的大哥,写的很好很强大,赞!离题了, 回来 ,41-10-10 =21 还有不少呢 。
接着封面图片,继续 , 继续缓存 增加 cover_image_url , 这下也不用找封面图片了,21 -10=11。
还有10个 用户查询(user), 也许您说了 , 这就不用了吧 ?联合查询不就行了吗,比如:查询时候加一个 :include => :user 不就搞定了吗 ? 这里我也有一个问题 , 加上联合查询查询速度怎么就那么的慢呢 ? 在我的笔记本上联合查询的速度甚至还比不上不用联合查询(使用多条查询)的速度,这里请教大家了, 你们有没有这个问题呢 ? 还是我的设置比如索引什么有问题? 还是继续我的思路:量小非君子,无毒不丈夫,把用户也缓存了吧,这下总能绕开联合查询的困扰吧 ?再说说我也只是需要知道用户的昵称而已 , 所以增加字段 :user_login,这下查询语句只有一条了。
也许有人问 , 干吗不用page 或者 fragement cache 来把这条查询也省了呢 ?呵呵 , 你说的很有道理呀 , 但是fragement 写起来就比较麻烦了,另外 比如说 “发布于2分种之前” 这种东西缓存起来就要增加一个时间的问题, 在没什么流量的情况下,还是将就凑合一下吧 , 写了一篇流水章, 大家凑合这看吧 , 顺便把 那个表的db migration 贴出 , 大家给看一下,为啥联合查询的速度会慢呢 ?如果谁还有兴趣想看看我写的东西的化,www.bujiande.com 不见得图片社区 , , 欢迎欢迎 , 你说这有打广告之嫌,那我就跟你说, 你吧之嫌给去掉, 就是打广告呀 :) , 另外我的空间还能放几个rails/php 程序 (最好你能有域名,我不想用我的2级域名了), 要是谁有有些创意的东东(要求原创) , 就放上来把 ,可以免费放x个月哦 :),这个我们下面谈...
class
CreateAlbums
<
ActiveRecord::Migration
def self.up
create_table :albums
do
|
t
|
t.integer :user_id, :
null
=>
false
t.string :user_login, :
null
=>
false
, :limit
=>
20
, :
default
=>
'
不见得
'
t.string :title, :
null
=>
false
, :limit
=>
128
t.text :description, :
null
=>
true
t.integer :cover_image_id #
default
image
t.string :cover_image_url #
default
image url
t.integer :category ,:
null
=>
false
, :
default
=>
10
#cache
for
tags
t.string :cached_tag_list
#cache
for
votes count
t.integer :cached_votes_count ,:
null
=>
false
, :
default
=>
0
#cache
for
comments count
t.integer :cached_comments_count ,:
null
=>
false
, :
default
=>
0
#popular
true
. popular
false
. incoming
t.
boolean
:bpopular ,:
null
=>
false
, :
default
=>
false
#
true
: published
t.
boolean
:bpublished ,:
null
=>
false
, :
default
=>
false
# freeze album cantains wrong message
/
pic
t.
boolean
:bfroze ,:
null
=>
false
, :
default
=>
false
t.timestamps
end
add_index
"
albums
"
, [
"
user_id
"
], :name
=>
"
fk_albums_user
"
add_index
"
albums
"
, [
"
bpopular
"
], :name
=>
"
fk_albums_popular
"
add_index
"
albums
"
, [
"
bpublished
"
], :name
=>
"
fk_albums_published
"
add_index
"
albums
"
, [
"
bfroze
"
], :name
=>
"
fk_albums_froze
"
add_index
"
albums
"
, [
"
category
"
], :name
=>
"
fk_albums_category
"
end
def self.down
drop_table :albums
end
end
上面就是 db migration,其实在共享空间里面就是要节约资源,在rails 程序里面来讲就是要节约db资源 (就像本文里面用的冗余字段)和 计算资源 (render) , 比如 fragment cache , 减少 render 所需的计算量 , 我也才接触 ruby/ rails 不到半年, 还是慢慢和大家探讨吧 :),
谁让咱们是程序员呢,自己写吧, 别用WordPress/PHP Board之类现成的了, 谁让现在 Rails 热呢, 咱也来趟趟这浑水。写啥?这个你就别问了, 想写啥写啥吧。没的可写?那咱们就有共同语言了,我也没有什么创意呀。 ,没有创意那就抄吧。这个也不会 ?那您就别当程序员了,哈哈 。抄啥呢 ?google ? 搜索算法也没学呢。 抄淘宝?估计马云就是你迈不过去的坎,突然发现了digg , 就是他了,发现用rails 抄digg简直是绝配,digg不是要投票吗?acts_as_voteable可以。digg不是要评论吗?acts_as_commentable 就行。Digg不是要标签吗?acts_as_taggable_on_steroids 来喽。再加上登录 restful_authentication , 分页插件 will_paginate ,不需要自己写啥,一个digg 不就出来了吗 :)
仔细看看digg , 发现这个家伙计算量还真不小,首先页面上每个帖子都是发布在几分钟之前,这个就不好缓存了吧 ? 估计是算出来得。然后 还计算你是否投了票, 居然还要看看这个帖子是不是你好友发的。。。唉,难道web 2.0 都这样?
要知道在共享主机上是没有mem cache 用的,每个数据都是直接在db(mysql) 里面读,Rails 最常用的 缓存 cache_fu 就没用喽。来来来, 算算我的程序需要多少次读,在没有:include => [:xxx] 的情况下 , 首页 要显示 10 个帖子 ,每个帖子要有个用户, 每个帖子还有 标签 ,还有投票数量 还有 评论数量 还有一个封面图片 , 开始算:
显示 10 个帖子 1 个查询 select * from xxxs limits => 10
用户 10个查询 select * form user where user_id = xxx
标签 10 个 具体怎么算 是acts_as_taggable_on_steroids干的,也是比较复杂
投票数量 10 个 count(*)
评论数量 也是10 个 count(*)
封面图片 10 个 select
总共 1 + 10 + 10 + 10 + 10 + 10 = 51个查询 呀
天哪 , 那台几百人用的共享主机怎么受得了?开始优化吧!
看到 acts_as_taggable_on_steroids 有缓存标签的功能 , 就是把主表增加一个字段cached_tag_list 每次读 tag 的时候,读这个字段就可以了。功能加上了 , 现在变成41个查询了。
联想到投票和评论, 咱也学学人家acts_as_taggable_on_steroids 把它们改成缓存吧 。主表加了2个字段cached_votes_count , cached_comments_count ,改了改acts_as_voteable和acts_as_commentable ,终于把这2个数字也缓存了 ,顺便说一下 voteabl/ commentable 这2个插件是同一个大哥写的, 写的还不是一般二般的烂, 你跟人家写taggable的大哥比比 , 怎么就这么不用心呢?还得让我2次加工,不知道我用这些插件就是为了偷懒的吗 :)接着表扬一下写taggable的大哥,写的很好很强大,赞!离题了, 回来 ,41-10-10 =21 还有不少呢 。
接着封面图片,继续 , 继续缓存 增加 cover_image_url , 这下也不用找封面图片了,21 -10=11。
还有10个 用户查询(user), 也许您说了 , 这就不用了吧 ?联合查询不就行了吗,比如:查询时候加一个 :include => :user 不就搞定了吗 ? 这里我也有一个问题 , 加上联合查询查询速度怎么就那么的慢呢 ? 在我的笔记本上联合查询的速度甚至还比不上不用联合查询(使用多条查询)的速度,这里请教大家了, 你们有没有这个问题呢 ? 还是我的设置比如索引什么有问题? 还是继续我的思路:量小非君子,无毒不丈夫,把用户也缓存了吧,这下总能绕开联合查询的困扰吧 ?再说说我也只是需要知道用户的昵称而已 , 所以增加字段 :user_login,这下查询语句只有一条了。
也许有人问 , 干吗不用page 或者 fragement cache 来把这条查询也省了呢 ?呵呵 , 你说的很有道理呀 , 但是fragement 写起来就比较麻烦了,另外 比如说 “发布于2分种之前” 这种东西缓存起来就要增加一个时间的问题, 在没什么流量的情况下,还是将就凑合一下吧 , 写了一篇流水章, 大家凑合这看吧 , 顺便把 那个表的db migration 贴出 , 大家给看一下,为啥联合查询的速度会慢呢 ?如果谁还有兴趣想看看我写的东西的化,www.bujiande.com 不见得图片社区 , , 欢迎欢迎 , 你说这有打广告之嫌,那我就跟你说, 你吧之嫌给去掉, 就是打广告呀 :) , 另外我的空间还能放几个rails/php 程序 (最好你能有域名,我不想用我的2级域名了), 要是谁有有些创意的东东(要求原创) , 就放上来把 ,可以免费放x个月哦 :),这个我们下面谈...
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
上面就是 db migration,其实在共享空间里面就是要节约资源,在rails 程序里面来讲就是要节约db资源 (就像本文里面用的冗余字段)和 计算资源 (render) , 比如 fragment cache , 减少 render 所需的计算量 , 我也才接触 ruby/ rails 不到半年, 还是慢慢和大家探讨吧 :),