4

このようなカスタムクエリがあります

self.account.websites.find(:all,:joins => [:group_websites => {:group => :users}],:conditions=>["users.id =?",self])

ここで、self はユーザーオブジェクトです

同じものに相当するSQLを生成することができました

見た目はこちら

sql = "select * from websites INNER JOIN group_websites on group_websites.website_id = websites.id INNER JOIN groups on groups.id = group_websites.group_id INNER JOIN group_users ON (groups.id = group_users.group_id) INNER JOIN users on (users.id = group_users.user_id) where (websites.account_id = #{account_id} AND (users.id = #{user_id}))"

SQL と ActiveRecordを十分に理解した上で、上記のクエリから得られた結果は、 find_by_sql(sql) one から得られた結果と比較して、(ほとんどが同意するだろう) 時間がかかる可能性があると想定しました。

しかし、驚くべきことに

上記の 2 つを実行すると、ロード時間に関して ActiveRecord カスタム クエリが ActiveRecord "find_by_sql" からリードしていることがわかりました。テスト結果は次のとおりです。

ActiveRecord カスタム クエリの読み込み時間

ウェブサイトの読み込み (0.9ms)

Web サイトの列 (1.0ms)

find_by_sql ロード時間

ウェブサイトの読み込み (1.3ms)

Web サイトの列 (1.0ms)

テストをもう一度繰り返しましたが、結果は同じでした(カスタムクエリが戦いに勝った)

違いはそれほど大きくないことはわかっていますが、通常のfind_by_sqlクエリがカスタムクエリよりも遅い理由を理解できません

誰でもこれについて光を共有できますか.

とにかくありがとう

よろしく ヴィレン・ネギ

4

2 に答える 2

1

検索ケースでは、クエリがパラメーター化されます。これは、データベースがクエリ プランをキャッシュできるため、クエリを再度解析してコンパイルする必要がないことを意味します。

find_by_sql の場合、クエリ全体が文字列としてデータベースに渡されます。これは、データベースがクエリの構造に対して実行できるキャッシュがないことを意味し、その都度解析してコンパイルする必要があります。

これをテストできると思います:この方法でfind_by_sqlを試してください(パラメータ化):

User.find_by_sql(["select * from websites INNER JOIN group_websites on group_websites.website_id = websites.id INNER JOIN groups on groups.id = group_websites.group_id INNER JOIN group_users ON (groups.id = group_users.group_id) INNER JOIN users on (users.id = group_users.user_id) where (websites.account_id = ? AND (users.id = ?))", account_id, users.id])
于 2011-02-22T12:38:03.490 に答える
0

理由はおそらく非常に単純です。カスタム SQL を使用すると、SQL クエリがすぐに実行のために db サーバーに送信されます。Ruby はインタープリター言語であるため、Rails は、実行のために実際の db サーバーに送信する前に、使用した ORM メタ言語に基づいて新しい SQL クエリを生成します。追加の 0.1 ミリ秒は、フレームワークがクエリを生成するのにかかる時間だと思います。

于 2011-02-22T11:56:54.723 に答える