はじめに
RailsでDBにインデックスを付与するメリットを体感するために、試験的に1万件のレコードを作成し、インデックスの有無で実行速度の比較をしてみました。
今回のケースではおよそ18%の速度UPという結果が出ています
※サクッと作成するため、DBはRailsのデフォルトであるSQLite3を使用しました。
2020/02/07追記
10万件のレコードだと20倍の差が出ていることを確認し、結果を追記しました。
@error_401 さんありがとうございます。
環境
OS: macOS Catalina 10.15.3
zsh: 5.7.1
Ruby: 2.6.5
Rails: 6.0.2.1
事前準備
$ rails new sampleapp
$ cd sampleapp
$ rails db:create
$ rails g model Post name:string description:string
$ rails db:migrate
irb(main):001:0> 10000.times do |p|
Post.create(name: "sample#{p}", description: "this is sample!#{p}")
end
準備が整ったら、実験開始です!
実行するコマンド
nameカラムを検索対象にし、find_by
メソッドでランダムな名前のレコードを1万回変数post
に代入するという内容です。
test.rb
を作成します。
require 'benchmark'
num_iteration = 10000
Benchmark.bm 10 do |r|
r.report "no-index" do
num_iteration.times do
post = Post.find_by(name: "sample#{rand(1..1000)}")
end
end
end
1.インデックスなしの場合
irb(main):001:0> require './test.rb'
user system total real
2.400283 0.353093 2.753376 ( 2.840555) # 1回目
2.456253 0.352958 2.809211 ( 2.914810) # 2回目
2.527288 0.383071 2.910359 ( 2.999960) # 3回目
測定の対象はuserの数値にします。
3回の平均はおよそ2.46秒でした。
2.インデックスありの場合
$ rails g migration add_index_to_post
class AddIndexToPost < ActiveRecord::Migration[6.0]
def up
add_index :posts, :name
end
def down
remove_index :posts, :name
end
end
$ rails db:migrate
これでインデックスがname
カラムに付与されたので、効果測定です。
再度test.rb
を実行します。
irb(main):001:0> require './test.rb'
user system total real
2.016621 0.349745 2.366366 ( 2.455184) # 1回目
2.037209 0.333974 2.371183 ( 2.465041) # 2回目
2.039167 0.327804 2.366971 ( 2.471504) # 3回目
3回の平均はおよそ2.03秒!
結論:およそ18%の速度UP
今回の単純なケースでは、**およそ18%**検索速度が上がりました!
もちろんtest.rb
の内容によって異なることもあると思いますが、指標の一つとして使えるのではないかと思います。
以上です!
2020/02/07追記 レコード10万件の場合
@error_401 さんよりコメントを頂き、早速レコードを増やした場合にどうなるか検証してみました!
検索条件の変化
- レコード数:10万件
- 検索条件:
name
カラムの検索条件をsample1
〜sample100000
へ変更。(回数は1万回で変更なし)
結果:インデックスなし
user system total real
39.969663 14.484736 54.454399 ( 54.855391) # 1回目
40.167824 14.695771 54.863595 ( 55.215927) # 2回目
40.057479 14.542640 54.600119 ( 54.955958) # 3回目
3回の平均はおよそ40.05秒
結果:インデックスあり
user system total real
2.007433 0.391915 2.399348 ( 2.546632) # 1回目
1.989761 0.376209 2.365970 ( 2.450146) # 2回目
2.029753 0.386575 2.416328 ( 2.566732) # 3回目
3回の平均はおよそ2.00秒!
10万件のレコード数だとなんと20倍速度が早くなりました!
ビックリしたのは、インデックスありだと1万件のときとほとんど数字が変わらないこと。
これはすごい
おわりに
最後まで読んで頂きありがとうございました
どなたかの参考になれば幸いです