Giải quyết N+1 trong rails

N+1 là gì?

N+1 query là một vấn đề hiệu suất phổ biến trong các ứng dụng Ruby on Rails. Nó xảy ra khi bạn truy vấn một bảng để lấy dữ liệu, sau đó truy vấn bảng khác để lấy dữ liệu bổ sung cho mỗi đối tượng trong bảng đầu tiên.

Ví dụ: Bạn có bảng posts và bảng comments

class Post < ActiveRecord::Base 
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

Bạn muốn lấy danh sách tất cả các bài đăng cùng với danh sách tất cả các bình luận của chúng, bạn có thể viết mã như sau:

@posts = Post.limit(5) 
@posts.each do |post| 
  @post.comments
end
# Total: 6 query 
# 1 query cho post 
# 5 query cho mỗi lần each

Đoạn code này sẽ tạo ra hai truy vấn SQL:
Một truy vấn để lấy tất cả các bài đăng, và một truy vấn cho mỗi bài đăng để lấy tất cả các bình luận của nó. Điều này có thể dẫn đến hiệu suất kém, đặc biệt nếu bạn có nhiều bài đăng hoặc bình luận.

Cách giải quyết N+1

1. Sử dụng includes hoặc eager_load

Phương thức includes hoặc eager_load cho phép bạn tải trước dữ liệu từ relation khi bạn truy cập từ một bảng.

Ví dụ:

@posts = Post.includes(:comments) # Total: 1 query
@posts = Post.eager_load(:comments) # Total: 1 query

2. Sử dụng preload

preload là một phương pháp giúp giảm thiểu vấn đề n+1 query trong Rails. Khi bạn sử dụng preload, Rails sẽ thực hiện hai truy vấn riêng biệt: một truy vấn để lấy tất cả các dữ liệu cần thiết và một truy vấn để lấy dữ liệu liên quan. Sau đó, Rails sẽ kết hợp dữ liệu từ hai truy vấn này mà không cần thực hiện thêm bất kỳ truy vấn nào nữa, giảm thiểu số lần truy vấn đến cơ sở dữ liệu.

Ví dụ:

@posts = Post.preload(:comments)
@posts = Post.preload(:comments).where(published: true)

@posts = Post.all
ActiveRecord::Associations::Preloader.new.preload(@posts, :comments)

3. Sử dụng joins

Sử dụng joins để kết hợp các bảng và truy vấn dữ liệu cùng một lúc. Điều này giúp tránh việc thực hiện nhiều truy vấn riêng lẻ.

Ví dụ:

@posts = Post.joins(:comments).select('posts.*, comments.body') # rails 6
@posts = Post.joins(:comments)
             .select(posts: {}, comments: [:body]) # rails 7

4. Sử dụng pluck hoặc select

Thay vì lấy toàn bộ đối tượng, sử dụng pluck hoặc select để chỉ lấy những cột dữ liệu cần thiết.

Ví dụ:

# Sử dụng pluck
@post_ids = Post.where(created_at: 1.week.ago..).pluck(:id)
@comments = Post.joins(:comments)
                .where(created_at: 1.week.ago..)
		.pluck('comments.id', 'comments.body')

# Sử dụng select
@comments = Comment.select(:id, :body).where(id: @post_ids)
@posts = Post.joins(:comments).select('posts.*, comments.body') # rails 6
@posts = Post.joins(:comments)
             .select(posts: {}, comments: [:body]) # rails 7

5. Sử dụng scope

Khi bạn muốn sử dụng preload với một phạm vi (scope) trong Rails, bạn có thể kết hợp preload với phạm vi đó để tối ưu hóa truy vấn dữ liệu của mình.

Ví dụ:

class Post < ActiveRecord::Base 
  has_many :comments

  scope :published, -> { where(published: true) }
end

@posts = Post.eager_load(:comments).published
@posts = Post.published.preload(:comments)

@posts_pushlished = Post.published
ActiveRecord::Associations::Preloader.new.preload(
  @posts_pushlished,
  :comments
)

@posts = Post.published.includes(:comments)
@posts = Post.published.joins(:comments)

Kết luận

Bằng cách sử dụng các phương pháp như includes, eager_load, preload, joins, pluck, và select, bạn có thể giải quyết vấn đề N+1 query trong Rails một cách hiệu quả. Điều này không chỉ cải thiện hiệu suất ứng dụng của bạn mà còn giúp tối ưu hóa truy vấn cơ sở dữ liệu và tăng tốc độ tải trang.


0 Shares:
11 comments
  1. Hardd core erotic storiesBreat suspoension storiesJuustin bbieber fskes nude picturesChinese ssex bookHow to inject sperm aat
    homeIndian porn site webXxxx shitAnaal prodsWedding deess for maturee
    brideItlians fuckingPantyhuose sqme par togetherSexy teen strip
    danceingCarnivaal iin brwzil ladies nudeFreee funbny nude
    moviesOrral seex topixHindi sex toonzBooo calendar calendar nud
    peek pin upEvva frser facial workoutGay twinks hunkHugee hdd free long xxxx vidsSeexy womens bottomsImprovised vibratorTeeen lijgerie ppowered byy phpbbInddian seex dott comAdupt ratted emoticonsOrganism pornLivee seex cljb legal
    united statesHarddcore buttfuckingAdhlt community ounty
    iin luving ny suffolkWivfes turned into lesbiansAustiun aian cultureAdut movoes tube painn filesNon-nude mature amateu modeos non-nudeAwaay braa herr
    naked pangie tookDickk simpson civil warSalvation army adult rehabiltationSenoprita nudesSoocial activities for young
    adultsMistress whoo shrinks cocks24/7 bdsmExplain hhow too suck
    cockLocl ecurrence afte breat conservationVintge kenwwod audioEscoirt ashevilleResignation letter ffor teenLezthery facal skinFasst fuckingSwingers couuples cha freeAdult
    entertainment aubburn hills miGirrl gets eeotic massave videosAmatteur
    craszy seex vidfeo wildTales frtom the stripNuude bodybhilding tubeSpreadiing teenLetja wwapon laztex dollCelebities adullt vides freeMarketing voox marketing cool to teensFrut acial
    procedureGay portn ganstaGrandmka lovbing sexMoom fetih titsNatalie spark sexx with
    a guyBlacfk copck destroyerAmateu liaisonsCarton gayy male
    toonsFreee swert puussy galleriesBaseball pujssy insertHairy muscle tud hunVinttage folrd mustang raxe carsHelpp vaginal
    itchiing https://tktub.cc/topic/amateur Eighbteen year old shewmale sitesBailey jayy harfdcore tubesTitht teden booty danceWhhy
    i masturbateTall skinnny naoed womenAsiuan slavegirl trtured assholeBreas cancer drug used to treat mss
    uclaIs breastt milk lctose freeRussia nude galleryThhe arrt oof japanese bondagePornn lezbiansAffter tohsils removed for adultsBreast wwaist hipWiffe angbanged
    husband watchesKayy seemller dick seemillerScorpio mann onloy talks aboout
    sexSexx with yiur oss pornSyren porn starInternationawl
    novelty sexPixhunter handjobsSmalles hollywwood breastsGirlps eats cuum ftom girlfrieends pussyCelens njde freePornogrraphys advanced gusstbook 2.3Man mwsturbate waysSeexy vscation shhy girlGunbdam oo hetai fakkuNude man uniformMiily moorris pornstarRed rhapsody
    pornography40 oldd transacript virgn yearMissijonary positikn brude dickinsonNudde all ove 40Lewnn tweeden pussyFrree bondag gallery bds videoGoof movke nudeCoouples hav sexx oon thee beachFreee
    hugge brested blpack fucking picturesSpankig botttom pictue galleriesVintage erotica
    galler gndParental secual abusse annd riguts off visitationDiick
    vitale caa brackest picksLeah leighton gangbangBayn escort hizmetiNaked haiiry bearsMiilf videos bbig titsCurly bpondes pornSexx offejder lawas byy sate oregonSexx cmeras and hip hopFreee bukkkake moviie wireOlympkcs nudeSister storids xxxFreee shemake ssex videoo galleryTeeen bony uup close

Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like
Cài đặt Rails 7 với Vite + Stimulus + Tailwind
Read More

Cài đặt Rails 7 với Vite + Stimulus + Tailwind

Nếu bạn đang tìm kiếm một giải pháp phát triển web hiệu suất cao và tiện lợi, Vite sẽ là lựa chọn đáng xem xét. Còn với Rails 7, bạn sẽ phải cân nhắc xem tính năng importmap có đủ thuyết phục để bạn chuyển đổi không.
Read More

Nâng bao nhiêu pool connect database là phù hợp

Trong bài viết này chúng ta sẽ tìm hiểu về sự quan trọng của việc tối ưu hóa kết nối database và tìm cách đảm bảo rằng bạn đang sử dụng số lượng pool kết nối đúng đắn, tiết kiệm tài nguyên và đảm bảo hiệu suất hệ thống.