なぜ
過去の遺産等でインデックスが機能しておらず、整理も困難なのでインデックスを指定したい。
具体的には、ページネーションで利用している Kaminari が total_count を取得する時にインデックスが指定されなかったため MySQL の USE INDEX (...)
を設定したかった。
どうやって
以下のスコープをモデルに記述する
scope :use_index, lambda { |*indexes|
from("#{self.table_name} USE INDEX(#{indexes.join(', ')})")
}
インデックスを利用したい時に指定する
Question.use_index(:index_questions_on_id).page.total_count
# (82.5ms) SELECT COUNT(*) FROM questions USE INDEX(index_questions_on_id)
# => 193887
まとめ
運用中でインデックス自体が整理されてない場合とかの応急処置としてはいいと思う。
本来なら不要なインデックスを削除して MySQL が自動で選択してくれるように最適化するのが一番なんだろうなあ。
ここ一ヶ月、久しぶりに Ruby 書いてて楽しいです。