読者です 読者をやめる 読者になる 読者になる

アナログCPU:5108843109

ゲームと音楽とプログラミング(酒と女とロックンロールのノリで)

HAVING句の使い方と速度検証

「HAVING句は使うな」とよく言われていたので未だに使ったことがないのですが、
なんだかよくわからないまま使わないというのも何なので、今更。

そもそもHAVING句とは、
「GROUP句でグループ化した結果を絞り込む」ためのものですね。

  • 各教科の得点平均が○点以上の生徒を抽出
  • 売上合計が○円以上の商品を抽出

などの用途に使えそうです。

基本的な文法は下記の通り。

SELECT
  カラム名
FROM
  テーブル名
WHERE
  条件
GROUP BY
  グループ化するカラム名
HAVING
  条件

ここで、約350万レコードのテーブルに対して
以下のようなクエリを打ってみました。

SELECT
  `id`
 ,AVG(`value`) AS `avg_value`
FROM
  `table`
GROUP BY
  `id`
HAVING
  AVG(`value`) > 5

tableテーブルより、idごとのvalue平均が5より大きいものを抽出、というクエリです。
3回実行して、処理時間を計ったところ

1回目 4.4302
2回目 4.2880
3回目 4.2740

となりました。
もうひとつ、同様の結果が得られる以下のクエリを打ってみました。
グループ化したデータをテーブルのように扱い、WHERE句で条件指定しています。

SELECT
  *
FROM
  (
    SELECT
      `id`
     ,AVG(`value`) AS `avg_value`
    FROM
      `table`
    GROUP BY
      `id`
  ) AS `hoge`
WHERE
  `avg_value` > 5

こちらも処理時間を3回計測したところ、

1回目 3.7066
2回目 3.6953
3回目 3.1217

となりました。

HAVING句を使った方が見た目にはスッキリしていますが、レコード数が多い場合は時間がかかってしまいます。
少ない場合は使用を検討してもいいかも、というところでしょうか。

参考:グループに対する検索条件の設定 - DBOnline
http://www.dbonline.jp/mysql/select/index10.html