質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
ActiveReports

ActiveReportsは、グレープシティ社が提供している帳票設計~管理、運用までの全ての機能を備えているオールインワン帳票ソリューションです。「セクションレポート」「ページレポート」「RDLレポート」の3つのレポートデザイン方式があり、使い分けて利用することができます。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

1回答

1632閲覧

allやpreloadでメモリにキャッシュできてない??

thesnowman

総合スコア154

ActiveReports

ActiveReportsは、グレープシティ社が提供している帳票設計~管理、運用までの全ての機能を備えているオールインワン帳票ソリューションです。「セクションレポート」「ページレポート」「RDLレポート」の3つのレポートデザイン方式があり、使い分けて利用することができます。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2020/06/14 03:17

自分の認識では、変数に代入すればメモリにキャッシュされることでSQLが発行しなくなくなるはずなのですが
変数に代入しても普通にSQLが発行していて混乱をきたしています。

以下はわかります

railsconsole

1irb(main):002:0> users = User.all 2User Load (0.6ms) SELECT "users".* FROM "users" LIMIT ? [["LIMIT", 11]]

ですが、以下でもSQLが発行しているのが謎です。
変数に代入したことでメモリにキャッシュされているはずなのでSQLが発行しないはずです。

railsconsole

1irb(main):003:0> users 2User Load (0.5ms) SELECT "users".* FROM "users" LIMIT ? [["LIMIT", 11]]

preloadも同様です。以下はわかります。

railsconsole

1irb(main):004:0> users = User.preload(:posts) 2 User Load (0.6ms) SELECT "users".* FROM "users" LIMIT ? [["LIMIT", 11]] 3 Post Load (4.5ms) SELECT "posts".* FROM "blogs" WHERE "posts"."user_id" IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) ORDER BY "blogs"."created_at" DESC

ですが、キャッシュしたはずなのに再度SQLが発行しています。

railsconsole

1irb(main):006:0> users 2 User Load (1.4ms) SELECT "users".* FROM "users" LIMIT ? [["LIMIT", 11]] 3 Blog Load (5.4ms) SELECT "blogs".* FROM "blogs" WHERE "blogs"."user_id" IN (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) ORDER BY "blogs"."created_at" DESC

質問

変数に代入したのに、変数を実行すると再度SQLが発行されるのは何故ですか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

user = User.all として、user.class としてみてください、
User::ActiveRecord_Relation となるとおもいます。
ActiveRecord_Relation は二つの顔を持ちます。

  1. 一つは それを表示させたり、eachしたりすると Userのインスタンスの配列の様な振る舞いをします。user = User.allの時点ではSQLは発行されず、その結果を利用する時点でSQLが実行されます。

user = User.all;1 とするとSQL実行されないのがわかります
user = User.all;user.count とすると違うSQL実行されます

2)ですが本質は 「SQL発行のデータを保存している」様なものなのです。
user = User.all のあと、user = user.order(:name) とか
user = user.where(name: "foo") とかして SQLの条件を追加してくことができます。

ですので、user とするとその時点での 1) の振る舞いを行うので、そこでSQLが発行されます

投稿2020/06/14 03:43

winterboum

総合スコア23567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thesnowman

2020/06/14 13:23

ありがとうございます! ではpreloadすると、N+1問題が回避できるのはなぜですかね?
winterboum

2020/06/14 13:51

その時点でメモリーに読み込まれます。
thesnowman

2020/06/14 13:55

だいぶわかってきた気がします
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問