はじめに
この記事は ミライトデザイン Advent Calendar 2022 の 20 日目の記事となっています。
先日はbucchさんの「ReactでGoogleMapの実装をしてみた」でした!
SQLクエリを作成していてテーブルを結合する際にUNION ALLを使う機会があったのですが、
UNIONっていうのもあるし、どっちがどのくらい処理速度速いんだろ?っと疑問に思ったので実際に処理速度を計測してみることにしました。
UNION と UNION ALL
どちらも、別々のSELECT文で取得したデータを縦に結合して一つのデータとすることができる構文です。
大きな違いは「重複するデータを排除するかしないか」です。
結合の際の注意点として以下は覚えておく必要があります。
- カラムの数が同じであること
- カラムの型が同じであること
今回の目的は「処理速度の比較」なので簡単に説明します。
UNIONについて
公式サイトを確認すると
UNION [ALL | DISTINCT]
とあります。
どうやらUNIONと記述するとデフォルトで、
UNION DISTINCT
になるようです。
実際にUNIONを試してみます。
使用するテーブル以下2つです。

ではUNIONを使って2つのテーブルを結合してみます。
SELECT id, name FROM test_a
UNION
SELECT id, name FROM test_b
「test_a」 と 「test_b」 とでの合計のデータ数は8件ですが、
重複していた2件が排除され6件となっています。
(塗りつぶしの部分)

UNION ALL
UNIONと違ってレコードの重複を排除しません。
ではUNION ALLを使って2つのテーブルを結合してみます。
SELECT id, name FROM test_a
UNION ALL
SELECT id, name FROM test_b
UNIONと違い2つのテーブルで重複している2件が排除されず8件全て取得されました。

実際に速度を比較してみる
ただ、その前にどっちが速いかの予想をしておきます。
それは・・・
UNION ALL
です。
理由はUNIONは「重複を排除」する処理を行っていて、
UNION ALLは行っていないからです。
行う処理は少ない方が速いんじゃないかな、という考えです。
前提
- 結合するテーブルは2つです。
- ここの説明では仮に「テーブルA」,「テーブルB」としておきます。
 
- 用意したカラムは「id(int型),name(varchar型)」の2カラムのみ
- 
UNIONとUNION ALLの比較をするために重複レコードが存在する必要があリますが、重複レコード数は全体の「20%」とし、Bテーブルに持たせます。
 (%はエイヤーで決めましたがこういうパターンは●%がいいよ、などありましたら教えていただけますと幸いです)
- クエリの実行は5回ずつ行い、比較は平均値で行います。
- MySQLのバージョンは「5.7.34」です。
 (テスト環境作成の都合上PHPMyAdminを使用しました)
【例】データ件数「10件」の場合に作成するテーブルイメージ

テーブルA,B共に件数は10件とし、テーブルBの件数の20%をテーブルAのデータと重複させます。
ここでは10件なので2件をテーブルAのデータと重複させます。
※実際のレコードは重複したレコードと重複しないレコードの順序はバラバラなことがほとんどかとは思いますが、今回は単純にUNIONとUNION ALLを比較したいだけなので重複データは並んでいます。
そのため実際は今回の計測結果よりも時間がかかることが予想されます。
計測するレコードの件数
今回6パターンのデータ取得の処理速度を計測してみます。
- 100件(20件重複)
- 1,000件(200件重複)
- 10,000件(2,000件重複)
- 100,000件(20,000件重複)
- 1,000,000件(200,000件重複)
- ※1,000,000件(重複なし)
※UNIONとUNION ALLは重複排除の有無なので重複しているデータを主としてで計測していますが、1パターンだけ、テーブルA,Bに重複がないとどのくらい違うのか?気になったので計測してみます。
計測結果
数字だけだと見づらいので平均値を使って縦棒グラフにしてみます。
(1,000,000件は文字がグラフに入りきらないので漢字で表記しています)

結果を箇条書きで記載します。
・100件〜10,000件まではUNION、UNION ALLには差があまりない
・100,000件、1,000,000件同士のテーブル結合だと顕著に速度差が出る
・UNIONよりUNION ALLの方が速い
・データ重複なしの場合でもUNIONよりUNION ALLの方が速い
データ件数が少ない場合はさほど差がありませんでしたが、
データ件数が多くなるとUNION ALLの方が処理速度が速いという予想通りの結果になりました。
データ重複がないパターンを計測する前は、
重複を排除しないUNION ALLの方が速いだろうけど、UNION、UNION ALLでそこまで差はでないんじゃないかと考えていましたが、
データ重複のパターンと同様の差が出る結果となりました。
結果を踏まえて
UNIONはデータが重複していようがいまいが「重複がないか」のチェックを行うので、
データ重複の有無はそこまで速度に関係がなさそうです。
今回データ重複がない場合において、UNION ALLの方が処理速度が速いという結果のため、
絶対にデータ重複がない、と知っている場合は、
UNIONとUNION ALLであれば速度的に優位なUNION ALLを選ぶべきということになります。
ただし仕様的にデータ重複を排除する必要がある場合、
優先順位は「速度 < 仕様」であり、仕様的にUNIONを選択することが正しければ、
速度的にUNION ALLが優位でもUNIONを使うべきですね。
おわりに
実際にUNIONとUNION ALLを使ったクエリの処理速度を計測してみて、
速度差を実感でき、状況に応じて使い分ける必要性があることを理解できたので良かったです。
今後、より効率の良いクエリ作成を心がけていきます!
さて、明日の記事はクエリマスターのNyokkiさんです。
クエリといえばNyokkiさん、Nyokkiさんといえばクエリ、非常に楽しみです。
参考



