考虑以下情况,我有两个表Users
和UserDetails
User
has_one :user_detail
UserDetail
belongs_to :user
我有一个案例,我必须搜索user_details并返回一个user_details
集合的结果。现在,我希望获得此user
的所有相关user_details
条记录。
我知道的一种方法是从user_id
结果中获取user_details
,并在User
模型中搜索此ID。
relevant_user_ids = user_details_search_result.pluck(:user_id)
User.where(id: relevant_user_ids)
其他方式是
User.joins(:user_detail)
.where("user_details.search_column = ?",search_requirement).
我想知道User表是否很庞大,加入user_details会显着减慢速度吗?
哪一个更好,还有其他办法。
答案 0 :(得分:1)
$("#upd_info").on('click', function()
{
var upd_name = $("#name_upd").val();
var upd_dob = $("#dob_upd").val();
var upd_phone = $("#phone_upd").val();
var upd_address = $("#address_upd").val();
$.ajax({
url: 'upd_patient.php',
data: {upd_id: id, n: upd_name, d: upd_dob, p:upd_phone, a:upd_address},
type: 'POST',
dataType: 'JSON',
success:function(res3)
{
$( "#dialog" ).dialog( "close" );
//here I need to access td of class nameid and change the value
},
error:function(res3)
{
console.log("Error Updating info");
}
});
也是一种选择。这可能比User.includes(:user_detail).where(user_details: {search_column: search_requirement})
(您的第二个示例)更快,具体取决于以下后续查询。即如果你以后要访问UserDetails属性,那么包含更快但是你需要更大的内存或根本没有这个,因为它会急切加载所有User和UserDetails记录,而不是加入哪个只会懒得加载用户记录,但如果您以后要访问UserDetail记录,则需要调用其他数据库查询。
我不确定.join
的速度有多快,但是如果你关心记忆,那么第一个使用pluck的例子就是我想要走的路。
奇怪的是,我尝试过运行测试:
(SSD,SQLite,Rails 4.2)
场景1(不调用关联记录)
.pluck
场景2(调用相关记录):
Post.destroy_all
User.destroy_all
time = {}
user = User.create!(name: 'foo')
5.times{ Post.create(title: 'hello', user: user) }
start_time = Time.now
1000.times do
user_ids = User.where(name: 'foo').pluck(:id); nil
posts = Post.where(user_id: user_ids); nil
posts.each{|post| 100.times{ puts post.title } }; nil
end
time[:using_pluck] = (Time.now - start_time) / 1000
start_time = Time.now
1000.times do
posts = Post.joins(:user).where(users: {name: 'foo'}); nil
posts.each{|post| 100.times{ puts post.title } }; nil
end
time[:using_joins] = (Time.now - start_time) / 1000
start_time = Time.now
1000.times do
posts = Post.joins(:user).where(users: {name: 'foo'}); nil
posts.each{|post| 100.times{ puts post.title } }; nil
end
time[:using_includes] = (Time.now - start_time) / 1000
puts time.to_yaml
# ---
# :using_pluck: 0.002787939
# :using_joins: 0.0027696689999999998
# :using_includes: 0.0027880739999999998
在场景1中(不调用关联记录),Post.destroy_all
User.destroy_all
time = {}
user = User.create!(name: 'foo')
5.times{ Post.create(title: 'hello', user: user) }
start_time = Time.now
1000.times do
user_ids = User.where(name: 'foo').pluck(:id); nil
posts = Post.where(user_id: user_ids); nil
posts.each{|post| 100.times { puts post.user.name } }; nil
end
time[:using_pluck] = (Time.now - start_time) / 1000
start_time = Time.now
1000.times do
posts = Post.joins(:user).where(users: {name: 'foo'}); nil
posts.each{|post| 100.times { puts post.user.name } }; nil
end
time[:using_joins] = (Time.now - start_time) / 1000
start_time = Time.now
1000.times do
posts = Post.includes(:user).where(users: {name: 'foo'}); nil
posts.each{|post| 100.times { puts post.user.name } }; nil
end
time[:using_includes] = (Time.now - start_time) / 1000
puts time.to_yaml
# ---
# :using_pluck: 0.006066561
# :using_joins: 0.006919676
# :using_includes: 0.00473808
稍微(我认为会很多)比.joins
更快,因为在.includes
中它不需要执行额外的查询以获取关联记录,而.joins
仍然可以获取附加记录。但是,在场景2(调用关联记录)中,.includes
比.includes
快,因为.joins
对数据库执行其他查询以获取关联记录,而.joins
已经.includes
急切地加载它,因此已经在记忆中。