68
73

More than 5 years have passed since last update.

パフォーマンスの良いSQLを記述しよう [SQLServer]

Posted at

はじめに

SQLのチューニングといえばインデックスをとりあえず作成する。といった対応が取られがちですが、数万レコード程度のデータ量ではあまり効果がありません。
またインデックスを乱立すると複数の条件がある時などにオプティマイザが誤作動を起こす要因ともなります。よって本当にインデックスがないことが原因なのか?を熟考する必要があります。

今回は、処理を早くするクエリの記述方法を備忘録がてらにまとめておこうと思います。

目次

  1. SELECT旬では必要なカラムのみを取得
  2. 暗黙の型変換
  3. WHERE句の左辺に算術演算子や関数を使用しない
  4. WHERE句は選択条件が少なくなる条件から記述
  5. UNION と UNION ALL の使い分け

1. SELECT旬では必要なカラムのみを取得

取得するカラムを絞る事で検索速度が上昇

Bad
SELECT *
FROM Order
Good
SELECT O.id
      ,O.orderName
FROM Order AS O

2. 暗黙の型変換

左辺に暗黙の型変換が発生するとインデックスが有効にならないため、検索速度が低下

前提条件
Order.id の型は nvarchar(15)
Bad(左辺がint型に暗黙の型変換がされる為)
SELECT O.id
      ,O.orderName
FROM Order AS O
WHERE O.id = 120000
Good
SELECT O.id
      ,O.orderName
FROM Order AS O
WHERE O.id = N'120000'

3. WHERE句の左辺に算術演算子や関数を使用しない

左辺に算術演算や関数を指定するとインデックスが有効にならないため、検索速度が低下

Bad
SELECT O.id
      ,O.orderName
FROM Order AS O
WHERE O.price * 2 > 20000
Good
SELECT O.id
      ,O.orderName
FROM Order AS O
WHERE O.price > 20000 / 2

4. WHERE句は選択条件が少なくなる条件から記述

検索条件が複数ある場合、抽出する件数が少なくなる条件から先に行う

前提条件
Order.type = 1 のレコードは10
Order.price > 20000 のレコードは1000
Bad(左辺がint型に暗黙の型変換がされる為)
SELECT O.id
      ,O.orderName
FROM Order AS O
WHERE O.price > 20000
  AND O.type = 1
Good
SELECT O.id
      ,O.orderName
FROM Order AS O
WHERE O.type = 1
  AND O.price > 20000

5. UNION と UNION ALL の使い分け

UNION を使用した場合、重複行を排除するためのソートが発生する。よって検索速度が低下
重複を許す場合は UNION ALL を使用する。

68
73
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
68
73