暗黙的なソートが発生する演算
- GROUP BY
- 集約関数(SUM, CONNT, AVG, MAX, MIN)
- DISTINCT
- 集合演算子(UNION, INTERSECT, EXCEPT)
- ウィンドウ関数
ソート処理がメモリでは足りずにストレージを用いて行われる場合は、パフォーマンスが大きく低下する。
そのため無駄なソートはなるべく避ける。
どう避ける?
GROUP BY
避けることは不可能
集約関数(SUM, CONNT, AVG, MAX, MIN)
極値関数であるMAX, MIXに関しては、引数列にインデックスを貼ることで、実テーブルへの検索を回避できる。
ソートを無くしている訳ではないが、検索を高速化できる。
DISTINCT
2つのテーブルを結合した結果を一意にするためにDISTINCTを用いている場合は、EXISTSで代用することでソートをお回避する。
以下のような会社一覧と、注文一覧があったとして、これまでに注文があった企業を出したい場合を考える。
company
company_id | company_name |
---|---|
1 | A |
2 | B |
3 | C |
4 | D |
orderhistory
company_id | price |
---|---|
1 | 100 |
2 | 200 |
3 | 300 |
3 | 400 |
1 | 500 |
3 | 600 |
3 | 700 |
SELECT
C.company_name
FROM
company C
INNER JOIN
orderhistory O
ON
C.company_id = O.company.ID
;
company_name
-------------
A
A
B
C
C
C
C
1対多の結合なので重複が出ます(INNER JOINは重複削除はしない)。
そのため一意にしようとしてDISTINCを使うのではなく、EXSITSを使うことでソートを避ける。
SELECT
C.company_name
FROM
company C
WHERE
(
SELECT
*
FROM
orderhistory O
WHERE
C.company_id = O.company.ID
)
;
company_name
-------------
A
B
C
集合演算子(UNION, INTERSECT, EXCEPT)
集合のため基本的に重複は許さない。そのため重複削除のためのソートが働く。
ただしALLオプションを付与することで、重複削除をしないため、ソートが発生しない。
ウィンドウ関数
避けることは不可能