RailsでのIN
エンジニアの皆さん、こんにちは!
そうでない方も読んでいただきありがとうございます。
今日のテーマはIN
今日のお話はRailsのActive Recordを使ったときのIN句のお話です。
おさらい
そもそもSQLにおいてIN句はどんなときに使うのかというと、連続ではない複数の値を指定したいときに使います。
例えば、CountryテーブルのID1、3、4のデータが欲しいときにはIN句を使って指定してあげます。
SELECT * FROM Country where ID IN (1, 3, 4)
Railsでの書き方
これをRailsのActive Recordを使って書くとこのように書けます。
ids = [1, 3, 4]
Country.where('id IN (?)', ids)
予め配列に値を入れておく必要がありますね。
ちなみに、ID1,3,4以外のデータが欲しいときに使うNOT INはこうなります。
ids = [1, 3, 4]
Country.where('id NOT IN (?)', ids)
実は
わざわざIN句を書かなくてもIN句を発行してくれてしまうのが、Railsの良いところであり、悪いところだと思っています。なぜなら、意図せずにIN句を使えてしまうということになるからです。用法を良く知ってから使いたいものです。
こんな風にwhere文を書きます。
ids = [1, 3, 4]
Country.where(id: ids)
この時に発行されるクエリは以下のようになっています。
SELECT 'countries'.* FROM 'countries'
WHERE 'countries'.'id' IN (1, 3, 4)
ではIN句を指定したActive Recordから発行されるクエリはどうだったかというとこうでした。
SELECT 'countries'.* FROM 'countries'
WHERE (ID IN (1, 3, 4))
若干の表記の違いはありますが、どちらもIN句を発行しています。
実行速度はいかに
クエリは実行速度が大事ですよね。
実は両者でこんな違いがありました。
Load (0.3ms)
SELECT 'countries'.* FROM 'countries'
WHERE 'countries'.'id' IN (1, 3, 4)
Load (0.6ms)
SELECT 'countries'.* FROM 'countries'
WHERE (ID IN (1, 3, 4))
ということは、where文だけで完結させた方が良いかもしれないですね。。。。
ちょっと残念でした笑
最後に
INを指定しなくてもIN句が発行されるというのは、たまたま指定忘れて見つけたものでした。
が、意外と違いがあるし、むしろその方が効率が良いというのは新たな発見でした。