简体   繁体   中英

How to achieve optimized mysql query in ruby on rails?

Model Structure: Comment Model has belongs_to relation and Resource Model doesn't have any relation.

class Comment < ApplicationRecord
 belongs_to :resource

end
Class Resource < ApplicationRecord

#No relation

end

This is my query: (Hope this is not n+1 as I have used includes)

comments = Comment.where(id: [5,6,7]).includes(:resource)
Hash[comments.map { |comment|
                          [comment.id, comment.resource] if comment.resource 
                      }]

Output that I got is this: In which 5 and 6 are comment_id and other is the resource _attributes

 5=>
  #<Resource:0x00007fa9b2a93518
   id: 3,
   url: "http://url.com",
   description: "og:description",
   title: "title",
   site_name: "og:site_name",
   image_url: "http://imageurl.com",
   video_url: nil,
   created_at: Mon, 28 Oct 2019 07:44:16 UTC +00:00,
   updated_at: Mon, 28 Oct 2019 07:44:16 UTC +00:00,
   embed_html: nil,
   url_hash: "df5ac6d4a1313ecb9949312d0258416a248333f68ae39aa1c7acd818e7d997e7",
   user_id: nil>,
 6=>
  #<Resource:0x00007fa9b2a92fa0
   id: 4,
   url: "http://url.com",
   description: "og:description",
   title: "title",
   site_name: "og:site_name",
   image_url: "http://imageurl.com",
   video_url: nil,
   created_at: Mon, 28 Oct 2019 07:44:16 UTC +00:00,
   updated_at: Mon, 28 Oct 2019 07:44:16 UTC +00:00,
   embed_html: nil,
   url_hash: "df5ac6d4a1313ecb9949312d0258416a248333f68ae39aa1c7acd818e7d997e7",
   user_id: nil>}

But I need more optimized query and output should be like:

5=>
  #<Resource:0x00007fa9b2a93518
   id: 3,
   url: "http://url.com",
   description: "og:description",
,
 6=>
  #<Resource:0x00007fa9b2a92fa0
   id: 4,
   url: "http://url.com",
   description: "og:description"
}

You can use INNER JOIN instead of Rails includes and don't instanciate Resource objects at all.

data = Comment.where(id: [5, 6, 7])
              .joins(:resource)
              .select(
                'comments.id AS comment_id',
                'resources.id AS r_id',
                'resources.url AS r_url',
                'resources.description AS r_desc'
              )
hash = Hash[data.map { |e| [e.comment_id, { id: e.r_id, url: e.r_url, desc: e.r_desc }] }]

It should give you result like that:

{
  5 => { id: 3, url: "http://url.com", desc: "og:description" },
  6 => { id: 4, url: "http://url.com", description: "og:description" }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM