前提
検索条件を細かく設定し、その条件に合致する結果を一覧で表示出来る画面があります。
検索対象となるのは、例としてイベントへの応募データを管理する下記のようなテーブル(enters)です。
CREATE TABLE `enters` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `event_id` BIGINT UNSIGNED NOT NULL, FOREIGN KEY (event_id) REFERENCES events(id), `name` varchar(255), `status` TINYINT UNSIGNED NOT NULL, `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `edited_at` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE `events` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` varchar(255), (省略) );
このテーブルの更新対象カラムはstatusとedited_atのみ。
event_idでイベントテーブル(events)と結合し、イベント名(varchar型)を取得します。
画面初期表示時は、自動で下記クエリを発行します。
SELECT * FROM enters INNER JOIN events ON enters.event_id = events.id ORDER BY created_at DESC LIMIT 100
検索実行時は、下記それぞれを任意で指定し、それを元にクエリを生成して発行します。
- イベント(event_id)
- 応募状況ステータス(status)
- 対象日時(created_at) ※開始と終了を両方または片方のみ指定可能
- 取得順序 ※降順(デフォルト)or昇順
- 取得件数 ※指定件数(デフォルト、上限1000とする)or全件
ただし、取得件数が全件の場合は、イベント/ステータス/対象日付いずれかを指定する必要があるものとします。
発行されるクエリ例
※"SELECT * FROM enters INNER JOIN events ON enters.event_id = events.id"は固定なので[SELECT...]として省略します
[SELECT...] ORDER BY created_at ASC LIMIT 1000 [SELECT...] WHERE event_id = 1 ORDER BY created_at DESC [SELECT...] WHERE event_id = 1 AND status = 0 ORDER BY created_at ASC LIMIT 1000 [SELECT...] WHERE event_id = 1 AND status = 0 AND created_at >= '2020-01-01 00:00:00' [SELECT...] WHERE created_at BETWEEN '2020-01-01 00:00:00' AND '2020-12-31 23:59:59' ORDER BY created_at DESC
実現したいこと
上記を踏まえ、まず最初の画面初期表示時に発行されるクエリの為に、"created_at"カラムにインデックスが必要だとは思うのですが、
それ以外のカラムについては"発行されるクエリ例"のようにクエリのパターンが多く、どのようにすべきか悩んでいます。
あらゆるパターンを考慮して複合インデックス含め作成しておくべきでしょうか。
なお、現状のレコード数は1000件にも満たないので、インデックスの有効性は無いと思っていますが、
一切レコードを物理削除することなく運用を続けていき、いずれチューニングを無視できないレコード数になった場合を想定して検討中です。
補足情報
MySQL 5.7
回答1件
あなたの回答
tips
プレビュー