はじめに
SQLのチューニングといえばインデックスをとりあえず作成する。といった対応が取られがちですが、数万レコード程度のデータ量ではあまり効果がありません。
またインデックスを乱立すると複数の条件がある時などにオプティマイザが誤作動を起こす要因ともなります。よって本当にインデックスがないことが原因なのか?を熟考する必要があります。
今回は、処理を早くするクエリの記述方法を備忘録がてらにまとめておこうと思います。
目次
- SELECT旬では必要なカラムのみを取得
- 暗黙の型変換
- WHERE句の左辺に算術演算子や関数を使用しない
- WHERE句は選択条件が少なくなる条件から記述
- 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 を使用する。