An Interest In:
Web News this Week
- April 23, 2024
- April 22, 2024
- April 21, 2024
- April 20, 2024
- April 19, 2024
- April 18, 2024
- April 17, 2024
April 22, 2022 09:09 pm GMT
Original Link: https://dev.to/kaziusan/how-to-resolve-n1-problem-on-rails-fl2
How to resolve N1 problem on Rails
4 key methods
- joins
- eager_load
- preload
- includes
joins
integrate by INNER JOIN
- doesn't cache association, so if you don't need data which is created again, you should use it.
- save memory allocated spaces because ActiveRecord object doesn't cache.
Skill.joins(:skill_category).limit(5)SELECT "skills".* FROM "skills" INNER JOIN "skill_categories" ON "skill_categories"."id" = "skills"."skill_category_id" LIMIT ? [["LIMIT", 5]]
eager_load
integrate by LEFT OUTER JOIN with cache
- faster than preload() because it creates only one SQL
- it can use WHERE in table which is integrated by JOIN (preload() can't do it)
Skill.eager_load(:skill_category).limit(5)SELECT "skills"."id" AS t0_r0, "skills"."name" AS t0_r1, "skills"."user_id" AS t0_r2, "skills"."skill_category_id" AS t0_r3, "skills"."created_at" AS t0_r4, "skills"."updated_at" AS t0_r5, "skill_categories"."id" AS t1_r0, "skill_categories"."name" AS t1_r1, "skill_categories"."reccomend" AS t1_r2, "skill_categories"."created_at" AS t1_r3, "skill_categories"."updated_at" AS t1_r4 FROM "skills" LEFT OUTER JOIN "skill_categories" ON "skill_categories"."id" = "skills"."skill_category_id" LIMIT ? [["LIMIT", 5]]
preload
use multiple SQLs with cache
- recommend to use it when you have big table which you don't wanna JOIN
- * it's impossible to use WHERE because it is not integrated by JOIN
Skill.preload(:skill_category).limit(5)# this oneSELECT "skills".* FROM "skills" LIMIT ? [["LIMIT", 5]]# and this oneSELECT "skill_categories".* FROM "skill_categories" WHERE "skill_categories"."id" IN (?, ?, ?, ?, ?) [[nil, 483], [nil, 583], [nil, 901], [nil, 181], [nil, 147]]
includes
if you use where, join, references method at least one, executes as eager_load, otherwise preload
# just includesSkill.includes(:skill_category).limit(5)# this oneSELECT "skills".* FROM "skills" LIMIT ? [["LIMIT", 5]]# and this oneSELECT "skill_categories".* FROM "skill_categories" WHERE "skill_categories"."id" IN (?, ?, ?, ?, ?) [[nil, 483], [nil, 583], [nil, 901], [nil, 181], [nil, 147]]
# using where()Skill.includes(:skill_category).where(skill_categories: { name: 'baseball' })# just one SQL like eager_load SELECT "skills"."id" AS t0_r0, "skills"."name" AS t0_r1, "skills"."user_id" AS t0_r2, "skills"."skill_category_id" AS t0_r3, "skills"."created_at" AS t0_r4, "skills"."updated_at" AS t0_r5, "skill_categories"."id" AS t1_r0, "skill_categories"."name" AS t1_r1, "skill_categories"."reccomend" AS t1_r2, "skill_categories"."created_at" AS t1_r3, "skill_categories"."updated_at" AS t1_r4 FROM "skills" LEFT OUTER JOIN "skill_categories" ON "skill_categories"."id" = "skills"."skill_category_id" WHERE "skill_categories"."name" = ? [["name", "baseball"]]
includes method is convenience as you see, but when other developer will see includes method, they need to think it means "preload" or "eager_load"
Original Link: https://dev.to/kaziusan/how-to-resolve-n1-problem-on-rails-fl2
Share this article:
Tweet
View Full Article
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To