SQL N+1問題、解決方法


開発中は、他のテーブルを参照する必要がある場合があります.このとき犯しやすいエラーの1つがSQL N+1の問題です.
1.SQL N+1の問題は何ですか?SQLはもう聞いたと思います.要約すると、現在業界で最も一般的に使用されているリレーショナル・データベースのデータを処理するために設計された言語です.しかし、SQLの文法を詳しく理解する必要はありません.(もちろん、詳しく知っていればもっと良かったのでしょうが…?)
なぜなら、ORMORMとは、使用されるコンピュータ言語で記述されたコードをSQL構文に自動的に変換し、データベースを認知および実行できるようにすることを意味する.Ruby on Railsを使用してコードを記述しても、このORMを使用してデータベースを間接的に操作できます.この場合、データベース内のクエリは1回ではなく、SQL N+1の問題と呼ばれる追加のN回です.本来の状況では、1日で終わることをN回実行して終了しているので、非常に非効率的な状況と思われるかもしれません.特に、実際に導入されたユーザー数が増加しているサービスでは、非常に致命的な問題です.
2.SQL N+1例
SQL N+1の問題が発生するべきではないことを知っているはずです.私の間違いを共有させてください.これは、トイがジェニーやメロン音楽のようなサービスを計画した時に犯したミスだ.
ユーザモデルはUserに設定され、音楽モデルはMusicに設定され、両者を接続する中間モデルはUserMusicに設定されている(プレイリストを実装するため).
個人のプレイリストを展示するために、loopでUserMusic件の記録を展示したいのですが、その際に私が展示したい情報は個人のプレイリストに追加された音楽のタイトル、音楽のアーティスト名、音楽のアルバム名などです.だから私は
music = user_music.music
これらのコードを通じてその音楽の情報を展示したい.クエリーを表示できます.
UserMusicをロードすると、Music Loadが合計5回ロードされます.プレイリストに音楽が5つあるため、クエリーが5回増加します.
3.SQL N+1の簡単な理解方法
もちろん、慣れている場合は、コードを書くときにすぐに問題点に気づくかもしれませんが、開発者本人を信じるのではなく、良い解決策のようです.bullet、すなわちgemについて説明します.これにより、gemでコードを必要とせず、インストールするだけで必要な機能を実現できます.railsについて詳しく説明した投稿があり、以下に参考リンクが残っています.gemをインストールすると、SQL N+1の問題を引き起こす可能性のあるコードが含まれている場合、次のポップアップメニューが表示されます.どうすればいいか教えてあげましょう射撃の名手

すなわち,gem構文を用いてこの問題を解決することができる.
4.SQL N+1の解決方法
ポップアップウィンドウのプロンプトに従って構文を追加すると、
<% user_musics.includes(:music).each do |user_music| %>
        <% music = user_music.music %>
ポップアップメニューが消えます.そして検索を確認してみると、

従来とは異なり、1回のクエリーでプレイリスト音楽をすべてロードできます.では、includesメソッドがSQL N+1の問題を解決できるのは何ですか?
5.SQL N+1の問題を解決するruby方法
この問題を解決するには、includeのような2つの方法があります.
5-1. includeデータナビゲーションの前に、テーブルを参照してデータをロードしてください.
5-2. preloaduser musicとmusicテーブルを接続して必要なデータをロードする方法.
5-3. eager_loaddefaultはincludeを使用するが、preloadまたはwhereメソッドを使用して他のテーブルを参照する場合はorderメソッドを使用する.eager_loadは、状況に応じて自動的に用途を変更する2つの属性を同時に持つ方法です.これまではN+1問題をincludeで解決すれば良いと思いましたが、includepreloadをそれぞれより効果的に指定した場合はコメントで教えてください:)
この部分ももう一度勉強しなければなりません.明確な答えを見つけることができれば、他の位置づけで議論します.
6.参照リンク
https://ideveloper2.tistory.com/80(gemについて)
https://velog.io/@khy226/Rails-SQL-N1-%EB%AC%B8%EC%A0%9C-%EA%B0%9C%EC%84%A0%ED%95%98%EA%B8%B0-feat.-includes-joins-preload(プリロード、ホットロードを含む)