19

次のクエリを実行すると:

SELECT * FROM `table1` 
 INNER JOIN table2 ON table2.number = table1.number

2秒以内に結果が得られます。に約600万件のレコードがtable2あり、に100万件のレコードがありますtable1

table2.numbertable1.numberインデックスが付けられます。

次に、存在しない番号のリストを取得したいと思います。このような:

SELECT * FROM `table1` 
 INNER JOIN table2 ON table2.number != table1.number

それは永遠にかかり、まだぶら下がっています..修正する方法は?

4

4 に答える 4

47

最初INNER JOINに の 1,000,000 行の 75% を返すとしますtable1。2 番目のクエリは、ご想像のとおり、他の 250,000 行を返しません。代わりに、デカルト積を作成し、一致する 750,000 行を削除しようとします。したがって、6,000,000×1,000,000-750,000 行を返そうとしています。これは、膨らんだ 6×10 12行の結果セットです。

おそらくこれが必要です:

SELECT * FROM table1
LEFT JOIN table2 ON table2.number = table1.number
WHERE table2.number IS NULL

table1これは、 に存在しない の行を返しますtable2

あなたも興味があるかもしれませんFULL OUTER JOIN:

SELECT * FROM table1
FULL OUTER JOIN table2 ON table2.number = table1.number
WHERE table1.number IS NULL AND table2.number IS NULL

これにより、他のテーブルに一致しない両方のテーブルの行が返されます。

于 2012-12-13T16:10:21.447 に答える
7

これが機能しない理由は、基本的にテーブル 1 のすべての行をテーブル 2 のすべての行と結合するためです。まだ結合するものが必要です。これを行う最善の方法は、左結合を実行し (つまり、table1 には結合しますが、table2 には結合しません)、次に、is null を持つ table2 のエントリがないことを確認します。次に、table2 に対して同じことを行う必要があります。

SELECT * FROM `table1` 
LEFT JOIN table2 ON table2.number = table1.number 
WHERE table2.number is NULL

UNION

SELECT * FROM `table2` 
LEFT JOIN table1 ON table2.number = table1.number 
WHERE table1.number is NULL
于 2012-12-13T16:07:54.970 に答える