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.
11 comments
Your article helped me a lot, is there any more related content? Thanks!
Your article helped me a lot, is there any more related content? Thanks!
Your point of view caught my eye and was very interesting. Thanks. I have a question for you.
Can you be more specific about the content of your article? After reading it, I still have some doubts. Hope you can help me. https://www.binance.info/register?ref=IXBIAFVY
I don’t think the title of your article matches the content lol. Just kidding, mainly because I had some doubts after reading the article.
Thank you for your sharing. I am worried that I lack creative ideas. It is your article that makes me full of hope. Thank you. But, I have a question, can you help me? https://www.binance.bh/bg/register?ref=V2H9AFPY
Your article helped me a lot, is there any more related content? Thanks! https://accounts.binance.bh/register/person?ref=IHJUI7TF
If yyou wouyld like tto griw your knowledge only kedp visitin thnis websitge andd bee updaated wiuth thee most recent nrws posted here.
ofvd9wuaptqfnuo4osec
Thank you for your sharing. I am worried that I lack creative ideas. It is your article that makes me full of hope. Thank you. But, I have a question, can you help me? gate io
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
Your point of view caught my eye and was very interesting. Thanks. I have a question for you.