こんにちは、編集長Kです。
開発もトレードも、スピードが命ですよね。
「データが増えたら、急にアプリが重くなった…」
あなたもこんな経験、ありませんか?
それ、実はSQLの書き方が原因かもしれません。
特に日付検索でやりがちなミスがあります。
それが恐怖の「関数フルスキャン」です。
この記事では、それを劇的に改善する方法をお伝えします。
難しい理論は抜きにして、実践重視でいきますね。
この記事で解説する手順の全体像はこちらです。
- 現状の「重いクエリ」を見つける
- Range Scan(範囲検索)へ書き換える
- インデックスの効きを確認する
前提条件として、以下の環境を想定しています。
- MySQLなどのリレーショナルデータベース
- Laravelなどのフレームワーク(生SQLでもOK)
- 対象カラムにインデックスが貼られていること
手順①:現状の「重いクエリ」を見つける
まずは、あなたのコードをチェックしましょう。
特定の日付のデータを取得したいとき。
こんな書き方をしていませんか?
// ダメな例(Laravelの場合)
$trades = Trade::whereDate('entry_date', '2026-03-16')->get();-- ダメな例(生SQLの場合)
SELECT * FROM tn_trades WHERE DATE(entry_date) = '2026-03-16';一見、シンプルで綺麗に見えますよね。
でも、これが大きな罠なんです。
カラムを DATE() という関数で包んでしまっています。
すると、データベースはどうなるでしょうか?
「関数がついてるから、インデックスの並び順が使えない!」
とパニックになります。
結果、全レコードを1件ずつ計算して探す羽目になります。
これが「フルテーブルスキャン」です。
データが数百万件あると、完全にフリーズします。
手順②:Range Scan(範囲検索)に書き換える
解決策はとてもシンプルです。
関数を外して、範囲(Range)で検索するだけ。
「この日の0時0分0秒から、23時59分59秒まで」
という条件に書き換えます。
まずは、下記を実行してください。
// 良い例(Laravelの場合)
$targetDate = Carbon::parse('2026-03-16');
$trades = Trade::where('entry_date', '>=', $targetDate->copy()->startOfDay())
->where('entry_date', '<=', $targetDate->copy()->endOfDay())
->get();-- 良い例(生SQLの場合)
SELECT * FROM tn_trades
WHERE entry_date >= '2026-03-16 00:00:00'
AND entry_date <= '2026-03-16 23:59:59';これでOKです。
見違えるほどレスポンスが早くなったはずです。
データベースは、関数のない生の値を好みます。
B-Treeインデックスという索引をそのまま辿れるからです。
これなら数億件のデータでも、数ミリ秒で結果が返ってきます。
まさに「Range Scan(範囲検索)」の威力ですね。
よくあるエラーと解決策
- Q「書き換えたのに、まだ遅いんだけど?」
- A
【インデックスが貼られていない】
そもそも entry_date にインデックスがないかもしれません。
マイグレーションでインデックスを追加しましょう。
【複合インデックスの順番が違う】
特定のユーザーのデータを絞り込む場合。
(user_id, entry_date) という順番のインデックスが必要です。
順番が逆だと効果が薄れるので注意してくださいね。
まとめ
お疲れ様でした!
今回は「関数フルスキャン」の撃退法を解説しました。
ほんの少しコードを変えるだけで、速度は劇的に変わります。
ぜひあなたのプロジェクトでも試してみてくださいね。
Trade Agencyでは、開発やトレードに役立つ実践的なノウハウを発信しています。
この記事が役に立ったと思ったら、ぜひブックマークをお願いします!
それでは、また次回の記事でお会いしましょう。

コメント