• トップ
  • ブログ一覧
  • Solr vs SQL 〜全文検索の速度を比較してみた〜
  • Solr vs SQL 〜全文検索の速度を比較してみた〜

    はじめに

    初めまして!今年(2025年)の6月に入社した片岡です。

    業務で初めてSolrを触る機会がありました。
    「SQLよりどのくらい速いのか!?」という素朴な疑問から、入門編としてまずはシンプルな条件で比較をしてみました。

    特に全文検索ってSQLのLIKE句だけだとどうしても遅くなったり、精度が微妙だったりしますよね。

    そこで今回は、全文検索に特化した検索エンジンSolrと、普段よく使うSQL(ActiveRecord)を使って、実際にどれくらい速度差があるのか簡単にベンチマークを取ってみました!

    Solrとは?

    Solr(ソーラー)はApacheが開発しているオープンソースの全文検索プラットフォームです。

    特徴としては:

    ・大量のデータに対して高速に全文検索できる

    ・形態素解析や表記ゆれへの対応が可能

    ・スコアリングやファセット検索など、柔軟な検索機能が豊富

    Railsとの連携にはsunspotやrsolrなどのgemを使うことで、ActiveRecordのモデルに検索機能を簡単に組み込めます。

    簡単なイメージで言えば「SQLでは限界がある検索を、もっと速く・柔軟にできる専用の検索サーバー」です!

    Round1: 【全文検索】速度比較

    目的

    MySQLのFULLTEXT検索とSolrで、できる限り条件(クエリ・返却件数)を揃えて全文検索を実行し、速度の違いを比較すること。
    本当はよく使われる LIKE '%keyword%' でも試したかったのですが、これはインデックスが効かず不公平になるため、今回は FULLTEXT検索 を採用しました。
    入門編として、まずはシンプルに「キーワード検索」での違いを確認してみましょう!

    前提

    • データ件数:約3万件(うちヒット20件想定の英字キーワードを投入)
    • MySQL:bodyFULLTEXT INDEX を作成済み

    揃えた条件

    • キーワード:SuperUniqueKeyword2025
    • 返却件数:row = 20
    • 返却フィールド:IDのみ
    • SQL:.pluck(:id)(ARオブジェクト化を避ける)
    • Solr:fl = id.hits.primary_key(DB再読込しない)

    コード(抜粋)

    1row = 20
    2query = 'SuperUniqueKeyword2025'

    # SQL(FULLTEXTでIDのみ)

    1sql_results = RoundOne
    2 .where("MATCH(body) AGAINST (?)", query)
    3 .limit(row)
    4 .pluck(:id)

    # Solr(qf=bodyでIDのみ)

    1RoundOne.search do
    2 adjust_solr_params do |p|
    3   p[:qf]      = 'body'
    4   p[:fl]      = 'id'
    5   p[:rows]    = row
    6  end
    7
    8  fulltext(query) { fields(:body) }
    9 end
    10
    11 solr_results = search.hits.map { |h| h.primary_key.to_i }

    結果

    ※実行時間は各クエリを3回実行し、平均値で算出

    項目SQLSolr
    レコード数30,025件30,025件
    実行結果件数20 件20 件
    実行時間0.0047 秒0.0035 秒

    チェックポイント

    • SQLEXPLAIN を実行して FULLTEXT インデックスが効いていることを確認済み
    • Solr.results ではなく .hits を利用し、DB再読み込みを避けて純粋に検索結果のみを比較
    • よく使うLIKE検索(%keyword%) はインデックスが効かず不公平になるため利用しない

    Round2:【最新50件取得(created_at降順)】速度比較

    目的

    SQLとSolrで、単純な「最新のN件を取得する処理」の速度差を比較する。

    前提

    • データ件数:約3万件
    • MySQL:created_at にインデックスを作成済み

    揃えた条件

    • 返却件数:row = 50
    • 返却フィールド:IDのみ
    • SQL:.pluck(:id)(ARオブジェクト化を避ける)
    • Solr:fl = id.hits.primary_key(DB再読込しない)

    コード(抜粋)

    1row = 50

    # SQL(created_at降順・IDのみ)

    1sql_results = RoundTwo
    2 .order(created_at: :desc)
    3 .limit(row)
    4 .pluck(:id)

    # Solr(全件対象+created_at降順・IDのみ)

    1search = RoundTwo.search do
    2 adjust_solr_params do |p|
    3  p[:q]    = '*:*'
    4  p[:fl]   = 'id'
    5  p[:rows] = row
    6  p[:sort] = 'created_at desc'
    7 end
    8
    9 solr_results = search.hits.map { |h| h.primary_key.to_i }
    10end

    結果

    ※実行時間は各クエリを3回実行し、平均値で算出

    項目SQLSolr
    レコード数30,000件30,000件
    実行結果件数50件50 件
    実行時間0.0055 秒0.0041秒

    チェックポイント

    • SQLEXPLAIN を実行してcreated_at インデックスが効いていることを確認済み
    • Solr.hits を使い、DBアクセスを伴わない純粋な検索処理だけを計測
    • 公平性のため、SQLもSolrも返却するのはIDのみに揃えて比較

    まとめ

    今回の比較は、「Solrを初めて触ってみたので、まずはSQLとどのくらい速度差があるのか」 をシンプルに試したものでした。

    結果としては、全文検索でも並び替えでも Solrのほうがわずかに速い という結果に。

    ただし、今回の条件はあくまで「入門的な比較」であり、件数やクエリ内容によってはSQLが有利になる場合もあります。

    例えば「最新数件を取得するだけ」ならDBインデックスが効きやすく、SQLの方が安定するケースもあります。

    一方で、

    • 複数フィールド検索
    • 表記ゆれへの対応
    • スコアリングを使った並び替え

    といった複雑な検索になるほど、Solrの倒立インデックスや専用の仕組みが活きてきます。

    そのため「シンプルなクエリならSQLでも十分。ただし柔軟性や拡張性を求めるならSolrを検討」というのが今回の気づきでした。今後はさらに実践的な条件でも比較を続けてみたいと思います!

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background