新手问题 sql 语句,find_each 和各种 joins,哪种更好?

egg_show · 2014年06月04日 · 最后由 egg_show 回复于 2014年06月04日 · 2707 次阅读
#one
A.where("condition").offset((page-1)*4).find_each(batch_size: 4) do |a|
  B.find(a.b_id)
  C.find(a.c_id)
  D.find(a.d_id)
end
#two
A.find_by_sql("一条sql语句,各种join")
#three
A.joins(:B).joins(:C).joins(:D).where("condition").offset((page-1)*4).limit(4)

Which one is best? (Based on Rails)

你要的其实是 includes

我觉得第三种能做到就做第三种,不行就第二种。第一种 find_each 是用来执行命令的,不是用来找东西的,batch_size 在这里有点误用。

#1 楼 @serco 哦,长姿势了,joins 没有 BCD 的数据,includes 才包含 BCD 的数据,是吧(加个 select 行的吧,只取想要的数据不更好吗)

#2 楼 @billy find_each 刚接触,一般怎么用来着,我还以为是类似批处理

@egg_show 是批处理,所以需要有东西“处理”,一般是做数据的增删改。找东西没有 ActiveRecord 或者 raw sql 找不到而需要批处理的。

#5 楼 @billy 如果我查询的 B 的数据有多条呢

A.all.each do |a|
  B.find_by_a_id(a.id)
end

这样感觉不效率的样子 - -循环中带查询

#5 楼 @billy 如果我查询的 B 的数据有多条呢

A.all.each do |a|
  B.find_by_a_id(a.id)
end

这样感觉不效率的样子 - -循环中带查询

这个不需要循环所有啊,一个 joins 的 scope 就搞定了。

A.joins(:bs)

#8 楼 @billy 我的意思是有 5 个 A(用户),每个 A 有 4 个 B(房子)数据,我现在要所有的 A 的数据,以及他们的每个房子的具体数据额,这样子,用 A.joins(:bs) 也行吗?

当然可以啊。这个 joins 就把所有有用户住的房子拉出来了。你还可以加 where 选定什么用户。

#10 楼 @billy 好像如果 A 和 B 在 join 的时候没有匹配的数据的话,会返回空,这时我还是希望要 A 的数据,只是显示没有 B 就行了,何解?

这个结果是对的,因为 joins 用的 INNER JOIN.

你如果想要即使不匹配的数据,就需要手动写 LEFT OUTER JOIN

Client.joins('LEFT OUTER JOIN addresses ON addresses.client_id = clients.id')

#12 楼 @billy thanks,把这茬给忘了 - -

#13 楼 @egg_show 听上去你的需求是把 A 和 B 的数据放到一个 xls 里?如果是这样的话别写 join 直接 includes 带分页的话 是否 select 出来特定项性能差别不大

#13 楼 @egg_show 不知道你在纠结什么,includes 就是 LEFT OUTER JOIN.

#15 楼 @serco includes 貌似是两个 select

#16 楼 @egg_show 那你加上 where 语句后就会变成一条 query,如果不需要 where 查询中包括 b,c,d 的话,可以直接 preload

#17 楼 @serco 怎样 preload 呢

#18 楼 @egg_show User.preload(:posts) 请翻一下 API

需要 登录 后方可回复, 如果你还没有账号请 注册新账号