最初に使用するための実行計画UNION
は、はるかに少ないステップを示しています。残念ながら、実行計画はすべてではありません。テーブルスキャン、論理読み取り、CPU 使用率もあるため、これがすべてではなく、すべてを終了し、データとデータに大きく依存します。あなたの指標。
重複を使用すると、最初のクエリのパフォーマンスが向上するはずです。これはUNION
、結合による重複の削除が結合の前に行われるため、テーブル 3 でのテーブル スキャンの回数が少なくなるからです。テーブル 1 とテーブル 2 に重複がない場合、違いはありません。
これは、いくつかのサンプル データで実証できます。私のサンプルはすべて次の 5 つのテーブルを使用します (T4 と T5 は単に出力をダンプするためのものなので、実行計画を確認するために SQL フィドルでページを何マイルも下にスクロールする必要はありません)。
CREATE TABLE T1 (ID INT NOT NULL);
CREATE TABLE T2 (ID INT NOT NULL);
CREATE TABLE T3 (FK INT NOT NULL, SomeValue VARCHAR(10) NOT NULL);
CREATE TABLE T4 (ID INT NOT NULL, SomeValue VARCHAR(10) NULL);
CREATE TABLE T5 (ID INT NOT NULL, SomeValue VARCHAR(10) NULL);
そして、すべて以下を使用してテストします (クエリ プランのキャッシュを排除するために逆方向にも実行されます)。
INSERT INTO T4
SELECT ID, SomeValue
FROM T1
LEFT JOIN T3
ON ID = FK
UNION
SELECT ID, SomeValue
FROM T2
LEFT JOIN T3
ON ID = FK;
INSERT INTO T5
SELECT ID, SomeValue
FROM ( SELECT ID
FROM T1
UNION
SELECT ID
FROM T2
) T
LEFT JOIN T3
ON ID = FK;
例 1 - T1 には、T2 にもある行が含まれています
INSERT INTO T1 (ID)
SELECT *
FROM GENERATE_SERIES(0, 40000);
INSERT INTO T2 (ID)
SELECT *
FROM GENERATE_SERIES(20000, 60000);
INSERT INTO T3 (FK, SomeValue)
SELECT *, 'VALUE'
FROM GENERATE_SERIES(10000, 50000);
SQL Fiddle の例は、T4 ( UNION
before JOIN
) への挿入のパフォーマンスが向上することを示しています。私はこれを 25 回実行し、T4 への挿入を 22 回実行しました。方程式からサーバーの負荷を取り除くのに十分なデータがないため、いくつかの異常があることは予想通りです。この例では挿入の順序が逆になっていますが、やはり同様の結果が見られました。
例 2 - table1 と table2 に重複はありません
INSERT INTO T1 (ID)
SELECT *
FROM GENERATE_SERIES(0, 30000);
INSERT INTO T2 (ID)
SELECT *
FROM GENERATE_SERIES(30001, 60000);
INSERT INTO T3 (FK, SomeValue)
SELECT *, 'VALUE'
FROM GENERATE_SERIES(10000, 50000);
この例では、実行時間は互いに非常に接近しており、どちらのメソッドがより高速に実行されるかが頻繁に切り替わります。
サンプルデータ
サンプルデータ 2
最後に、すでに述べた点を繰り返しますが、重複を予期していない場合/重複を気にしない場合はUNION ALL
パフォーマンスが向上しますが、重複がない場合は両方の方法でパフォーマンスがほぼ同じになるはずなので、両方の方法が改善されるはずです等量で。私はこれをテストしていませんが、これを確認するために使用したテスト データを変更するのは大規模な作業ではありません。
編集
SQL Fiddle でクエリを試してみたところ、ローカル マシンで行った場合よりもはるかに多くの分散が示されました。したがって、これらの例を参考にして、自分のサーバーでテストを行ってください。フェアを作成する方がはるかに簡単です。テスト環境!