作者giive (lala)
看板Ruby
标题从 SQL 看 ActiveRecord 实做方式 (2) :Count
时间Mon Oct 30 13:05:15 2006
出自我的Blog
http://lightyror.blogspot.com/2006/10/sql-activerecord-2-count.html
自从上次写了 从 SQL 看 ActiveRecord 实做方式 ,我养成了写完程式,会顺便看 SQL 的好习惯。今天早上我花点时间来测试一下,计算资料库数量的多寡的重要函式 Count 。之前我要写数量多寡都是直接用 .size 来写。像是找出 User 里面名字叫做 a 的所有资料数量
User.find_all_by_nickname('a').size
结果出现的 SQL 是
User Load (0.000444) SELECT * FROM users WHERE (users.`nickname` = 'a' )
妈呀,真是刺激。也就是说,他会将所有的 nickname 为 a 的资料全部传出来(1),塞给一个 array(2) ,然後计算 array 的数量大小。假设资料数量一大起来,1的传输时间会大幅度的增加,2的 array 所占用的记忆体也会暴增。
再来,我来测试一下,关联性 has_many 遇到计算数量时候的作法
a = User.find(1)
a.blogs.size
出现的 SQL 是
User Load (0.000339) SELECT * FROM users WHERE (users.id = 1) LIMIT 1
Blog Load (0.000320) SELECT * FROM blogs WHERE (blogs.user_id = 1)
妈呀,真是跟上面一样刺激,会遇到的问题也跟上面一样麻烦。也就是说,用 .size 的作法完全不可取。
我们换个方式,我看到了关联性 has_many 支援一个 function ,就是在has_many 後面加入一个 _count
a = User.find(1)
a.blogs_count
出现的 SQL 是
User Load (0.000339) SELECT * FROM users WHERE (users.id = 1) LIMIT 1
Blog Load (0.000320) SELECT * FROM blogs WHERE (blogs.user_id = 1)
天呀,居然跟 .size 一样,真是刺激的作法(有写跟没写一样)。
这个时候,脸上不禁出现三条线,那麽简单的事情 Ruby on Rails 会没考虑到?怎麽可能,我通常遇到这个问题时,会先 Chanllege 自己一下『应该是我不熟悉,而是没有这个东西』。这时拿出居家旅行必备良书 Agile Web Programming with Rails 出来拜一拜,发现到如果我们使用
User.count(["nickname = ?" , "a"])
出现的 SQL 是
SQL (0.000324) SELECT count(*) AS count_all FROM users WHERE (nickname = 'a')
而关联性资料库
a.blogs.count
出现的 SQL 是
SQL (0.000296) SELECT count(*) AS count_all FROM blogs WHERE (blogs.user_id = 1)
拉拉,就是这个就是这个。 在 DB 处理 select count(*) 本来就会比 select * 来得快而且省记忆体。并且在资料库传输到程式语言里面只传一个数字远比传一组 array 来得快。传到程式语言里面变数占用的记忆体也有天壤之别。
结论是请大量使用 .count ,而请不要使用 _count ,或是 .size 来计算资料库数量的大小。
--
lighty RoR 是一个介绍 lighttpd , SQLite , Ruby and Rails 的 Blog
http://lightyror.blogspot.com/
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.218.90.242
1F:→ roga:经验啊..写的真好,感谢你的用心 10/30 15:32