こんにちは!
n+1問題がわかんなくて今週仕事の合間に
ずっと調べて記事にしようと思ってました。
ただただ自分のアウトプットをしてるだけだと
なんか嫌々記事書いてるみたいで楽しくないし、
そもそもn+1問題に関する記事なんて腐る程あると
思うので僕の大好きな呪術廻戦を交えて
説明して行こうかなと思います。
この記事ではn+1問題の具体的な説明を
僕的に分かりやすく抽象化したものなので
もっとコード用いた具体例を見たい!って
人は他のブログ見てください。
てか一回n+1問題の記事をみてわけわからんかったら
この記事見てからもう一回見てみてね。
あと呪術廻戦知らない人ゴメンなさい。。。
ネタバレも含んでいるからあんまり見たくない人は
ここで読むのやめてください!!
n+1問題とは
そもそもN+1問題とは
テーブル間にアソシエーションが
組まれている際に、データベースへの
アクセス回数が多くなり、
アプリケーションのパフォーマンスが
低下してしまいます。
さてこれを呪術廻戦で例えていきましょう。
夏油傑の術式
何で例えようかと思いましたが、
夏油傑の術式にしました。
夏油傑の術式は呪霊操術といって、
捉えた呪霊をポケモンみたいに味方にできる
スーパーチート術式です。
夏油傑からみるN+1問題
夏油傑は呪術廻戦0巻で約4,000体もの
呪霊を保有していたとされます。
これをテーブルで表してみましょう。
usersテーブル
id | curse users | cursed Technique |
---|---|---|
1 | 夏油傑 | Curse Manipulation |
curseテーブル
id | spell | user_id |
---|---|---|
1 | 切り裂き女 | 1 |
2 | 虹龍 | 1 |
3 | 疱瘡婆 | 1 |
4 | 玉藻前 | 1 |
5 | 巨大なペリカン | 1 |
curseテーブルは夏油さん4000体も呪霊書けないんで
割愛します。
てか全部登場したわけではないし。
例えばここで夏油傑がIQ12だったとします。
夏油は4000体の呪霊を全部召喚して
テロを起こしたいと考えます。
そこで夏油は1体ずつ呪霊の情報を処理し
放っていきます。
1体ずつということは4000回もこの行為を
行わないといけません。
僕だったら、もう24体目ぐらいで
やめてます。
てかこんなことしてたら呪力量に限界がきちゃいますし
もうテロどころじゃないですよね。
とまあこれがn+1問題です。
もう一度言いますが、
テーブル間にアソシエーションが
組まれている際に、データベースへの
アクセス回数が多くなり、
アプリケーションのパフォーマンスが
低下してしまいます。
夏油と呪霊には主従関係が組まれており、
夏油が呪霊ストックへのアクセス回数が
多くなると呪力量が著しく減り、
パフォーマンスが低下してしまいます。
夏油傑からみるincludesメソッド
ではこれをどうすればいいのか?includesメソッドを使用することで、
引数に指定された関連モデルを1度のアクセス
でまとめて取得できます。
includesメソッドも詳しい記述方法は他の方の
記事を参考にしてください。
includesメソッドを使えばn+1問題が解決するんや!!
ぐらいに思ってもらえたらOKです。
夏油も喜んでくれます。
じゃ例えます。
ここで夏油傑のIQ45に上がったとします。
夏油が「一括で4000体放てるようにしたらええねや!!」と
当たり前のことをようやくようやく気付いたとします。
こうすれば夏油の呪力量は減りすぎないし、
パフォーマンスも落ちませんね