惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tailwind CSS Blog
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 【当耐特】
The Cloudflare Blog
博客园 - 聂微东
博客园 - 司徒正美
量子位
博客园 - 三生石上(FineUI控件)
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
G
Google Developers Blog
Apple Machine Learning Research
Apple Machine Learning Research
罗磊的独立博客
酷 壳 – CoolShell
酷 壳 – CoolShell
Y
Y Combinator Blog
S
SegmentFault 最新的问题
T
The Blog of Author Tim Ferriss
P
Proofpoint News Feed
Google DeepMind News
Google DeepMind News
Blog — PlanetScale
Blog — PlanetScale
有赞技术团队
有赞技术团队
A
About on SuperTechFans

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Rails Interview #1: The N+1 Query Problem
Hassan Farooq · 2026-06-22 · via DEV Community
Cover image for Rails Interview #1: The N+1 Query Problem

Hassan Farooq

You ship a /posts index page. It renders 50 posts, and for each one it shows the author's name with post.author.name. QA says the page is slow, and the logs are full of repetitive SQL.

  1. What is this problem called, and why is it happening?
  2. How would you detect it, in dev and in a running app?
  3. How do you fix it, and what's the difference between the main fixing strategies?

Answer: N+1 queries

What it is and why it happens

This is the N+1 query problem. One query loads the 50 posts, then Active Record fires one more query per post to load post.author. That's 1 + N queries (1 for posts, 50 for authors) when it could be 2, or even 1. Active Record associations are lazy by default, so the author isn't loaded until you call post.author. Do that inside a loop and you get a round trip per record.

How to detect it

  • Dev logs: you'll see the same SELECT ... FROM authors WHERE id = ? over and over with different IDs. That repetition is the tell.
  • The Bullet gem: built for this. It warns you in dev when you should add eager loading, and also when you're eager-loading something you don't need.
  • An APM in production (Sentry, New Relic, Scout): flags endpoints firing a lot of queries.
  • Tests: assert on query count with something like assert_queries or an RSpec matcher so CI catches a regression before it ships.

How to fix it

Eager-load the association:

# N+1
@posts = Post.all
@posts.each { |p| puts p.author.name }   # 1 + 50 queries

# Fixed
@posts = Post.includes(:author)
@posts.each { |p| puts p.author.name }   # 2 queries

There are four tools, and they don't do the same thing:

Method What it does When to use it
preload Loads the association in a separate query and matches it in memory You just need the data and aren't filtering or ordering by the association
eager_load One LEFT OUTER JOIN that loads everything in a single query You need to filter or order by the association and read its attributes
includes Defaults to preload, but switches to eager_load if you reference the association in a where or order Your usual default. Let Rails decide
joins INNER JOIN for filtering or sorting. Does not load the association into memory You need to filter by the association but don't read its attributes

The trap: joins alone does not preload. If you joins(:author) and then call p.author.name in the loop, you're right back to N+1. Reach for includes or eager_load when you actually read the association's attributes.