具体的なテーブルを使ったクエリ例
ここでは、以下の4つのテーブルを結合するシナリオを想定します。
users
: ユーザーの基本情報 (id, name, gender, departmentId
)
departments
: 部署情報 (id, departmentName
)
jobs
: 職種情報 (id, jobTitle
)
salaries
: 給与情報 (userId, jobId, salaryAmount
)
これらのテーブルを使って、ユーザーの性別、部署名、職種名、給与情報を取得するクエリは以下のようになります。
SELECT
u.id AS userId,
u.name AS userName,
CASE u.gender
WHEN 1 THEN '女性'
WHEN 0 THEN '男性'
ELSE '不明'
END AS genderText,
d.departmentName,
j.jobTitle,
s.salaryAmount
FROM
users AS u
INNER JOIN
departments AS d ON u.departmentId = d.id
INNER JOIN
salaries AS s ON u.id = s.userId
INNER JOIN
jobs AS j ON s.jobId = j.id
WHERE
u.gender IS NOT NULL AND s.salaryAmount > 0;
クエリの解説
FROM users AS u
: usersテーブルをuというエイリアス(別名)で指定します。
INNER JOIN departments AS d ON u.departmentId = d.id
: usersテーブルのdepartmentId列とdepartmentsテーブルのid列を結合します。
INNER JOIN salaries AS s ON u.id = s.userId
: usersテーブルのid列とsalariesテーブルのuserId列を結合します。
INNER JOIN jobs AS j ON s.jobId = j.id
: salariesテーブルのjobId列とjobsテーブルのid列を結合します。
WHERE u.gender IS NOT NULL AND s.salaryAmount > 0
: WHERE句を使って、データにnull値が含まれていないことや、給与が0より大きいレコードに絞り込んでいます。
これにより、不要なデータの読み込みを防ぎ、パフォーマンスを向上させます。
このクエリは、4つのテーブルをINNER JOINで結合し、それぞれのテーブルから必要な情報を抽出しています。
より高速化を目指すなら
さきほどのクエリで10万件のデータを爆速で抽出するためのテクニックは、主にインデックスの最適化とクエリ自体の効率化の2つに集約されます。
クエリは既に適切に書かれていますが、データベースの物理的な構造がパフォーマンスを大きく左右します。
1. インデックスの最適化
インデックスは、テーブルの特定の列を高速に検索するための「本の索引」のようなものです。
特に、結合(JOIN
)や絞り込み(WHERE
)に使用される列にインデックスを張ることが非常に重要です。
クラスタ化インデックス(Clustered Index
)
設定箇所: users.id, departments.id, jobs.id
理由:
これらのid列は通常、主キーとして設定され、テーブルの物理的なデータの並び順を決定します。
JOIN
する際に、SQL Serverはクラスタ化インデックスを利用して、関連するデータを瞬時に見つけ出すことができます。
users
テーブルで10万件のデータを全件取得する場合、このインデックスをスキャンするのが最も効率的です。
非クラスタ化インデックス(Non-Clustered Index
)
設定箇所: users.departmentId, salaries.userId, salaries.jobId
理由:
これらの列はJOIN句で使用されていますが、クラスタ化インデックスキーではないため、非クラスタ化インデックスを張るのが最適です。
このインデックスは、データの物理的な並び順とは別に作成され、高速な検索を可能にします。
絞り込み条件:
WHERE句で使用されているusers.gender
やsalaries.salaryAmount
にもインデックスを張ることで、絞り込み処理がさらに高速化します。
2. クエリ自体の効率化
クエリは既に最適化されていますが、以下の点を確認することでさらにパフォーマンスが向上する可能性があります。
必要な列だけを選択する
SELECT句で*(すべて)を使わず、必要な列だけを指定することで、ネットワーク転送量とメモリ使用量を削減できます。今回のクエリは既にこのテクニックが使われています。
適切なJOINタイプを使用する
INNER JOIN
は、結合キーが両方のテーブルに存在するレコードだけを返すため、最も効率的なJOINタイプの一つです。今回のクエリは適切にINNER JOINが使用されています。
WHERE
句で絞り込む
WHERE
句で絞り込むことで、処理対象となるデータ行を減らすことができます。
今回のクエリではu.gender IS NOT NULL AND s.salaryAmount > 0
という絞り込みが適用されています。
もし、特定の部署や職種など、さらに絞り込める条件があれば追加することで、より高速な抽出が可能です。
まとめ
10万件のデータを爆速で抽出する究極のテクニックは、インデックスを適切に設計することに尽きます。
特にJOIN
句やWHERE
句で使用される列にクラスタ化インデックスや非クラスタ化インデックスを張ることが、データベースのパフォーマンスを劇的に改善する鍵となります。
クエリ自体は非常に効率的に書かれているため、データベースの物理設計がパフォーマンスのボトルネックになっている可能性が高いです。