中山テック 代表の中山です。

さて、代表はデータベースに触れてきており、SQLの組み立てやテーブル構成・設計はもちろん

チューニングも経験してきました。

その中で、経験が浅い時代は「UNION ALL」でつまづいたことがありました。

クエリが長いので「読みたくない」という気持ちはもちろん、段々何したいのかわからなくなるのです。

さらに使いどころもわからない、遅くなるのではないかという思いもあり避けてきました。

それでしばらく触れる機会もなかったので、放置してましたがチューニングが必要となった時

UNION ALLを使う必要が出てきたので嫌々頑張った所、案外単純な構造であることに気づきました。

気付きが遅い代表と同じ轍を踏んでほしくないため、本日はUNION ALLの説明したいと思います。

一言で言えば「OR条件」のことです。

じゃあOR使えばいいじゃん!と思うかもしれませんが、レコードが増えるとそうはいきません。

例えば一意(全部異なる)のユーザIDがあり、指定された2つのレコード取りたいといった場合。

さらに、インデックス(索引、どこに何があるか)が指定されているとします(つーかする)。

結果が数件ならいいんですが、100万件ありましたとなるとどうなるか。

100万件あるということは、全体で150万とか500万件ある可能性があります。

OR条件にするとインデックスが効かず、全体500万あったとしたらまず500万件を全走査します。

ちなみに1件の検索に0.001秒掛かるとしたら5000秒(83分)掛かります。

これがネットショップのページなら、次画面行くのに83分掛かるというのは耐えられますか?

代表は、ムリデス 笑

そのためにUNION ALLでOR条件を作って抽出します(インデックスも効きます)。

索引があればどの辺にあるか目星がつきますので検索時間の短縮が見込めます。

ただ、ルールがあって「取得対象のデータ数が一致」してないとSQLエラーとなる点です。

※SELECTの後の取得対象カラム数のこと

データ取得数はor条件を使った時も同じになるように、UNION ALLでも同じです。

ただし検索条件(WHERE)句はAが少なくて、Bが多い場合でも問題ありません。

あくまでも取得するカラム数が一致していればいいのです。

  • 関連記事

クエリの組み方

上記を例にして単純なクエリを作ってみます。

前回のブログで作ったテーブル名「SANKANBA」、データはID・名前・取った年とします。

※データが少ないですが、あくまでも例として・・・

ID名前3冠以外の代表レース
000001st. lite00(なし)
000002shinzan20(有馬記念)
000003mr. c.b13(天皇賞秋)
000004shinbori rudolph05(天皇賞春)
000005narita brian20(有馬記念)
000006deep impact08(宝塚記念)
000007orfevre20(有馬記念)
000008contrail19(ジャパンカップ)
000009mejiro l'Amone00(なし)
000010still in love00(なし)
000011apapane06(ヴィクトリアマイル)
000012gentildonna19(ジャパンカップ)
000013armond eye19(ジャパンカップ)
000014daring Tact00(なし)
あれ、三冠馬ってこんなに多かったっけ・・・?

では三冠以外の代表的なレースで「天皇賞秋」「天皇賞春有馬記念」を取った馬を

検索したい場合で「or」を使わない場合はこうなります。

SELECT
  id,
  name
FROM
  SANKANBA
WHERE
  sankanigairace = '05'
UNION ALL
SELECT
  id,
  name
FROM
  SANKANBA
WHERE
  sankanigairace = '20'

UNION ALLをorと考えて、前をA・後をBと考えると「A or B」ということになります。

ねっ、簡単でしょう?

A or BがそれぞれSELECT文になっただけ

ちなみにALLを付けない場合は重複行がまとめられず、複数行として表示されます。

※もちろん、状況によっては複数行で表示されることは問題ありません

データが多い

上記はデータが少ない、取得対象のデータ(selectの後の表示対象カラム)も

少ないですがデータが多い場合はどうするのでしょうか。

UNION ALLがorと同義なのであればやることは一緒です。

まとめ

いかがでしたでしょうか。

UNION ALL(UNION)を使用するとついついSQL文が長くなってしまいます。

それで読むのが嫌だ!という方も多いので、是非UNION ALLをorにしてあげて分割しましょう。

逆に使えるようになると便利ですし、何よりパフォーマンスの向上に繋がります。

是非当ブログをご覧になって頂いて参考となることを切に願います。

※中山テックに掲載しているゲーム画像の著作権、商標権、その他知的財産権は、当該コンテンツの提供元に帰属します


おすすめの記事