Shikata Ga Nai

Private? There is no such things.

第25回:クエリを速くする工夫:インデックス・サブクエリ活用術

Hello there, ('ω')ノ

「SQLでデータを取るのはいいけど、遅い…」 「大量データを扱ったら、結果が出るまで待たされる」

こんな経験はありませんか? データ量が増えると、クエリ(データ抽出の命令)のパフォーマンスが非常に重要になります。


✅ まずは、なぜSQLが遅くなるのか?

SQLが遅くなる主な原因は以下の通りです:

原因 説明
データ量が多すぎる 数百万件のデータをそのまま検索しようとすると時間がかかる
WHERE句やJOINの条件が不適切 条件の順番や項目が最適でないと全件スキャンになる
重複処理や集計が多い 無駄なGROUP BYやDISTINCTが処理を重くする
インデックスが使われていない 検索を速くする道筋がない状態

🟩 ① インデックスとは?検索の“目次”を作ろう!

📚 インデックスのイメージ:

本で言う「索引ページ」や「しおり」のようなもので、特定の列に対して早く探せるような目印をつける仕組みです。

🔍 例:社員テーブルからIDで検索したい場合

SELECT name FROM employees WHERE employee_id = 1234;

employee_id にインデックスがあれば、ピンポイントで検索できます。 なければ、全社員データを1件ずつ見て探す=時間がかかる!

✅ インデックスが効果的な列

  • 主キー(IDなど)
  • WHERE句でよく使う列
  • JOINやORDER BYの対象になりやすい列

🧠 注意点:

  • インデックスは速くなるが、作りすぎると更新が遅くなる!  → 適度な数で、重要な列だけに設定しましょう。

🟨 ② サブクエリ・共通テーブル式(CTE)で分割して処理!

🔸 サブクエリとは?

1つのSQLの中に、別のSELECT文を埋め込む書き方です。 データを段階的にフィルタリングしたり、比較対象を明確にしたりするときに使います。

例:一番給料が高い人の名前を取り出したい

SELECT name
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);

→ 「サブクエリ」で最大値を先に取得し、それと一致するデータを抽出しています。


🔹 共通テーブル式(WITH句)

サブクエリを分離し、見やすく再利用可能にしたバージョンです。

例:月ごとの売上集計を一度作って、あとで加工する

WITH monthly_sales AS (
  SELECT month, SUM(sales) AS total
  FROM sales_data
  GROUP BY month
)
SELECT * FROM monthly_sales WHERE total > 1000000;

→ 一度まとめてから、その結果に条件をつけるので処理の流れが分かりやすく、最適化しやすい


📊 インデックスとサブクエリの使い分け例

目的 使うべき技術 理由
特定IDや日付で絞り込みたい インデックス 高速検索に最適
複雑な条件を段階的に処理したい サブクエリ or WITH句 可読性と効率UP
集計後にさらにフィルタしたい 共通テーブル式(WITH) 集計→分析の流れがスムーズ
データ量が数十万件以上ある 両方併用 インデックス+構造分割が効果的

✅ SQLチューニングの初歩テクニックまとめ

テクニック 内容 効果
インデックス設定 よく検索する列に目印をつける 処理時間を劇的に短縮
サブクエリ活用 条件を階層的に処理する 複雑なSQLを整理しやすい
WITH句(CTE) サブクエリを名前付きで管理 見やすく、再利用しやすい
不要な列はSELECTしない SELECT *は避ける ネットワーク負荷を減らす

✨ まとめ:速いSQLは“設計”がすべて!

ポイント 解説
インデックスは検索の道しるべ 適切に使えば劇的に高速化できる
サブクエリ・WITH句で構造を整理 段階的にデータを処理してミスと重さを回避
パフォーマンス改善は分析の前提 時間がかかるSQLでは、業務に使えないことも
ツール任せにせず、基本を知っておく BIツールの裏側でSQLが動いていることを意識しよう!

Best regards, (^^ゞ