今やってる仕事で、インデックスの貼られていない項目同士で結合した際にパフォーマンスが悪く、データ量が多い本番では使い物にならなかったので、備忘録として残そうと思います。
前提条件
検証に使用したコードは下記です。
p Time.zone.now.strftime("%H:%M:%S") p ActiveRecord::Base.connection.select_all('select a.* from users as a left join users as b on a.name = b.name').to_hash.length p Time.zone.now.strftime("%H:%M:%S")
usersテーブルに100万件のデータが登録されています。
初めに、インデックスなしのケースを検証してみたのですが、1時間経っても処理が終わらなかったので、途中で中断しました。
※それだけ時間がかかることがわかりました。
MySQLでの実行計画は以下のようになっていました。
実行計画確認用のクエリ
explain select a.* from development.users as a left join development.users as b on a.name = b.name;
次に、インデックスを貼って検証してみました。
3回測定し、約19秒という結果になりました。
MySQLでの実行計画は以下のようになっていました。
indexが使用されているのが分かります。
今後は、大量データを扱う際は、本番想定のデータで検証が必要と痛感しました。