🤨 N + 1問題とは


💎 何ですか。


簡単に言えば、多くのSQLクエリはループ内で実行されます

💎 例えば


データベースには2つのテーブルがあります
▼ カントリーテーブル
ID
名称
1
日本
2
ポーランド
▼ フードテーブル
ID
田舎の人
名称
1
1
寿司
2
1
ラーメン
3
1
うどん
4
2
ピエロ
5
2
コレット
6
2
時明

国名を取得する


( Rubyコードを使うつもりです)
# SELECT * FROM country;
Country.all.each do |country|
  put country.name
    # Japan
    # Poland
end

別のテーブルをループで呼び出す


# SELECT * FROM country;
Country.all.each do |country|
  put country.name
    # Japan
    # Poland

  # SELECT * FROM food WHERE country_id=1;
  # SELECT * FROM food WHERE country_id=2;
  # 😫 😭 if country table had 200 records, 200 query would be executed!!! OMG
  country.foods.each do |food|
    put food.name
      # sushi
      # ramen
      # udon
      # pierogi
      # kotlet
      # ziemniaki
  end
end

💎 どのように解決するには?

  • に加わる
  • 熱心な荷
  • 結合


    統合テーブル!
    # SELECT * FROM country INNER JOIN food ON country.id=food.country_id
    # 😀 😀 only 1 query !
    Country.join(:food).all.each do |country|
      country.foods.each do |food|
      end
    end
    

    熱心な負荷


    完全に結合のようなテーブルを統合しませんが、最初に選択を実行します!
    # SELECT * FROM country;
    # SELECT * FROM food WHERE country_id IN(1,2)
    # 😀 😀 only 2 queries !
    Country.includes(:food).all.each do |country|
      country.foods.each do |food|
      end
    end
    
    ⭐ Rubyで熱心な負荷を使いたいなら、

    💎 不利


    メモリリークは、最初に大きな選択を実行する必要があります