メインコンテンツへスキップ

DB設計におけるスロークエリー対策とは?原因と改善方法をわかりやすく解説

·2020 文字·5 分

Webアプリケーションのパフォーマンス低下の原因としてよくあるのが スロークエリー(Slow Query) です。

特にデータ量が増えると、適切なDB設計をしていない場合 クエリの実行時間が極端に遅くなることがあります。

この記事では DB設計におけるスロークエリーの原因と対策について、実務でも使える改善方法をわかりやすく解説します。


スロークエリーとは
#

スロークエリーとは、実行に時間がかかるSQLクエリのことを指します。

一般的には以下のような状態を指します。

  • SQLの実行時間が長い
  • データベースのCPU使用率が高い
  • APIレスポンスが遅くなる
  • データ量が増えると急激に遅くなる

スロークエリーは アプリケーションのパフォーマンス低下の大きな原因になります。

多くのデータベースでは、一定時間以上かかるクエリをスロークエリーとして記録できます。

例えばMySQLでは、以下の設定でスロークエリーをログに記録できます。

slow_query_log = 1
long_query_time = 2

この場合、2秒以上かかったクエリがスロークエリーとして記録されます。


スロークエリーログを確認する
#

MySQLではスロークエリーをログに記録できます。

SHOW VARIABLES LIKE 'slow_query_log';

スロークエリーログを有効にすると、時間のかかるSQLを特定できます。

主な確認ポイント

  • 実行時間
  • 実行回数
  • フルスキャンの有無

スロークエリーが発生する主な原因
#

スロークエリーの原因は主に以下です。

  • インデックス不足
  • N+1問題
  • 不適切なJOIN
  • 大量データのフルスキャン
  • 不適切なDB設計

これらを理解することで、パフォーマンス問題を事前に防ぐことができます。


インデックス設計を行う
#

スロークエリー対策で 最も効果が高いのがインデックス設計です。

インデックスが無い場合、データベースは **テーブル全体をスキャン(フルスキャン)**します。

SELECT * FROM users WHERE email = '[email protected]';

email にインデックスが無い場合、すべてのレコードを検索します。

インデックスを追加

CREATE INDEX idx_users_email ON users(email);

これにより検索速度を大幅に改善できます。

複合インデックス
#

複数カラムで検索する場合は複合インデックスを利用します。

CREATE INDEX idx_users_email_status
ON users(email, status);

複数条件の検索では、単一インデックスより高速になることがあります。

LIMITで取得件数を制限する
#

大量データを取得するとクエリが遅くなる原因になります。

SELECT * FROM logs;

SELECT * FROM logs
ORDER BY created_at DESC
LIMIT 50;

取得件数を制限することでレスポンスを改善できます。

キャッシュを活用する
#

頻繁に実行されるクエリはキャッシュを活用すると改善できます。

  • Redis
  • Memcached
  • アプリケーションキャッシュ

キャッシュを利用することで、DBアクセスを減らせます。


N+1問題を防ぐ
#

ORMを使用している場合、N+1問題が発生することがあります。

SELECT * FROM users;
SELECT * FROM posts WHERE user_id = 1;
SELECT * FROM posts WHERE user_id = 2;
SELECT * FROM posts WHERE user_id = 3;

ユーザー数分クエリが発行されるため、パフォーマンスが悪化します。

対策

SELECT users.*, posts.*
FROM users
JOIN posts ON users.id = posts.user_id;

JOINを使用することでクエリ回数を減らせます。


SELECT * を避ける
#

SELECT * は便利ですが、パフォーマンスに影響することがあります。

理由

  • 不要なカラムまで取得する
  • ネットワーク転送量が増える

改善例

SELECT id, name FROM users;

必要なカラムだけ取得することで処理を軽くできます。


適切なJOIN設計
#

JOINの設計が悪いとクエリが非常に遅くなります。

ポイント

  • JOINカラムにインデックスを付ける
  • 不要なJOINを減らす
  • JOIN数を最小限にする

SELECT orders.id, users.name
FROM orders
JOIN users ON orders.user_id = users.id;

orders.user_id にインデックスを付けることで高速化できます。


EXPLAINでクエリを分析する
#

スロークエリーを改善するには クエリの実行計画を確認することが重要です。

EXPLAIN SELECT * FROM users WHERE email = '[email protected]';

確認するポイント

  • type
  • key
  • rows
  • Extra

これにより フルスキャンが発生していないか確認できます。


DB設計で意識すべきポイント
#

スロークエリーを防ぐためには DB設計の段階から意識することが重要です。

主なポイント

  • 適切なインデックス設計
  • 正規化されたテーブル構造
  • JOIN回数を減らす設計
  • 検索カラムの最適化

設計段階で対策しておくことで、大規模データでもパフォーマンスを維持できます。


よくあるスロークエリーのパターン
#

フルテーブルスキャン
#

インデックスが無い場合、すべてのデータを検索します。

type: ALL

これはパフォーマンス問題の典型例です。


ORDER BYでインデックス未使用
#

SELECT * FROM users ORDER BY created_at;

created_at にインデックスが無い場合、ソート処理が重くなります。


よくある質問
#

スロークエリーの目安は?
#

一般的には 1秒以上のクエリがスロークエリーとして扱われることが多いです。

インデックスを付けすぎるとどうなりますか?
#

インデックスが増えると INSERT / UPDATE が遅くなる可能性があります。


まとめ
#

スロークエリーは、Webアプリケーションのパフォーマンス低下の大きな原因になります。

主な対策は以下です。

  • インデックス設計
  • N+1問題の回避
  • SELECT * を避ける
  • JOIN最適化
  • EXPLAINでクエリ分析

これらを意識することで、大規模データでも高速なDB処理を実現できます。


📘 関連資料
#

MySQL公式ドキュメント
著者
ゆーふー
Web開発、インフラ、AI技術に興味があるエンジニアです。日々の学びを記録しています。

関連記事

👤 運営者プロフィール

運営者プロフィール画像

ゆーふー

メガベンチャーで働く現役Webエンジニア(歴約2年)。
フロントエンドからインフラ構築、セキュリティ対策まで、実務で得た「現場のリアルな技術知見」を発信しています。