0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SQL Serverでの処理速度の改善

Posted at

具体的なテーブルを使ったクエリ例
ここでは、以下の4つのテーブルを結合するシナリオを想定します。

users: ユーザーの基本情報 (id, name, gender, departmentId)

departments: 部署情報 (id, departmentName)

jobs: 職種情報 (id, jobTitle)

salaries: 給与情報 (userId, jobId, salaryAmount)

これらのテーブルを使って、ユーザーの性別、部署名、職種名、給与情報を取得するクエリは以下のようになります。

sample.sql
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.gendersalaries.salaryAmountにもインデックスを張ることで、絞り込み処理がさらに高速化します。

2. クエリ自体の効率化

クエリは既に最適化されていますが、以下の点を確認することでさらにパフォーマンスが向上する可能性があります。

必要な列だけを選択する

SELECT句で*(すべて)を使わず、必要な列だけを指定することで、ネットワーク転送量とメモリ使用量を削減できます。今回のクエリは既にこのテクニックが使われています。

適切なJOINタイプを使用する

INNER JOINは、結合キーが両方のテーブルに存在するレコードだけを返すため、最も効率的なJOINタイプの一つです。今回のクエリは適切にINNER JOINが使用されています。

WHERE句で絞り込む

WHERE句で絞り込むことで、処理対象となるデータ行を減らすことができます。
今回のクエリではu.gender IS NOT NULL AND s.salaryAmount > 0という絞り込みが適用されています。
もし、特定の部署や職種など、さらに絞り込める条件があれば追加することで、より高速な抽出が可能です。

まとめ

10万件のデータを爆速で抽出する究極のテクニックは、インデックスを適切に設計することに尽きます。

特にJOIN句やWHERE句で使用される列にクラスタ化インデックス非クラスタ化インデックスを張ることが、データベースのパフォーマンスを劇的に改善する鍵となります。

クエリ自体は非常に効率的に書かれているため、データベースの物理設計がパフォーマンスのボトルネックになっている可能性が高いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?