LoginSignup
20
8

More than 3 years have passed since last update.

【Rails】DBのカラムにインデックスを付与する/しない場合での速度比較をしてみた

Last updated at Posted at 2020-02-06

はじめに

RailsでDBにインデックスを付与するメリットを体感するために、試験的に1万件のレコードを作成し、インデックスの有無で実行速度の比較をしてみました。

今回のケースではおよそ18%の速度UPという結果が出ています:point_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する
$ rails new sampleapp
sampleappディレクトリに移動
$ cd sampleapp
db_createする
$ rails db:create
Postモデルの作成
$ rails g model Post name:string description:string
db_migrateする
$ rails db:migrate
事前に1万件のデータを登録
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を作成します。

sampleapp/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.インデックスなしの場合

rails_consoleで実行
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
XXXXXXXXXXXXXXXX_add_index_to_post.rb
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を実行します。

rails_consoleで実行
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カラムの検索条件をsample1sample100000へ変更。(回数は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万件のときとほとんど数字が変わらないこと。
これはすごい:dizzy_face:

おわりに

最後まで読んで頂きありがとうございました:bow_tone1:

どなたかの参考になれば幸いです:relaxed:

参考にさせて頂いたサイト(いつもありがとうございます)

20
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
8