私はMySQLデータベースでRails 2.3.5を実行しています。 Books
とUsers
の間にHABTMの関係があり、特定の書籍リスト(書籍名の配列で定義)を持つすべてのユーザーを取得しようとしています。ActiveRecordを実行するとSQLの遅さがHABTM関係にある
私は、ユーザーのリストを取得しfind
コールを実行することができるよ。しかし、これは非常に遅いことが判明
User.find(
:all,
:joins => :books,
:conditions => { :books => { :name => book_names } }
)
を。同じクエリのために
User.find_by_sql([
"SELECT users.* FROM users
INNER JOIN books_users ON users.id = books_users.user_id
WHERE books_users.book_id IN (SELECT id FROM books WHERE books.name IN (?))",
book_names
])
find_by_sql
呼び出しがおよそ200を取るのに対し、find
コールが自分のコンピュータ上でおよそ3000ミリ秒かかります:SQLで遊んでた後、私は次の呼び出しは、はるかに高速に動作し、同じ結果を取得することがわかりましたミズ;これは速度差の大きさ全体です。私は犯人は元find
コールは、次のと同等のダブルINNER JOIN
SQLクエリに翻訳されているという事実とは何かを持っている疑いがある:
[
"SELECT users.* FROM users
INNER JOIN books_users ON users.id = books_users.user_id
INNER JOIN books ON books_users.book_id = books.id
WHERE books.name IN (?)",
book_names
]
私の質問は以下のとおりです。
- 誰もが知っていますなぜこれが当てはまるのですか?ダブル
INNER JOIN
が入れ子になったSELECT
クエリを持つ私の単一のINNER JOIN
よりも遅いのはなぜですか? find_by_sql
呼び出しは、RailsがHABTM関係に提供する組み込みサポートを実際に利用していません。特に、books_users
のジョイン・テーブルには、Railsがサポートしているものが一般的に開発者から抽象化されています。これを隠す呼び出しであるfind
を使用して同じクエリを指定する方法はありますか?
'books_users'テーブルの' book_id'フィールドと 'user_id'フィールドにインデックスを作成しましたか? –
Ack ...私は何かを忘れていたことを知っていた。これだった!インデックスを追加した後、検索クエリは15ミリ秒かかるようになりました。 – Claw
@dmarkow:回答として追加してください。私たちはあなたにポイントを与えることができます – nathanvda