2011-10-25 5 views
3

この2つの文のどちらが速いのですか教えてください。mysql - "INNER JOIN"または "IN"。どちらが速いの?

第一文:

SELECT DISTINCT(t1.user_id) FROM table_users as t1 WHERE t1.user_town IN (SELECT t2.town FROM table_towns as t2) 

2番目の文:

SELECT DISTINCT(t1.user_id) FROM table_users as t1 
    INNER JOIN (SELECT t2.town FROM table_towns as t2) as t3 ON t1.user_town = t3.town 

私が使用して選択しますが、通常はもう少し複雑です。 可能であれば、私は値を渡すことができるので、IN(...)を使用しようとします。

+0

結果をSELECT t1。*からSELECT DISTINCT(t1.user_id)に変更して、異なる結果を避けるようにしました。それは通常私が本当に気にしているからです – Seeker

答えて

1

彼らはどちらも私の目にかなり似ています。いずれの場合においても

SELECT t1.* 
FROM table_users t1 
INNER JOIN table_towns t2 ON t1.user_town = t2.town 

、クエリのためにEXPLAIN planが言うと、ライブデータにいくつかのベンチマークを実行しているかが表示されるはずです。私は、MySQL is not particularly good with subqueriesがあることを考えると、単一のSELECTは、優れたパフォーマンスを提供することをかなり確信しています。

0

あなたはそれを測定し、確かめるために説明計画を発行する必要があります。しかし、私はそれらのどちらも使用しません:

select u.* from table_users as u 
inner join table_towns as t on u.user_town = t.town 
0

INはMySQL用です。むしろEXISTSを使用してください。

INNER JOINはかなり高速ですが、結果は必ずしも同じではありません。この場合(または類似の)結果を得るには、グループ化するか、distinctが必要な場合がありますが、この場合は安全だと思います。

内部結合を使用している場合は、MySQLがそれらをうまく処理しないため、副選択にしないでください。ちょうどtable_townsテーブル自体に参加してください。

+0

これは、最新のMySQLバージョンではもはや真実ではありません。 'IN(select ....)'が最適化されました。 – Johan

+0

もう殺していないかもしれませんが、比較ではまだずっと遅いです。 – GolezTrol

+0

@Johan - これはどのバージョンが有効ですか?あなたが本当であると信じているだけでなく、実際のテストから**を聞くことに興味がありますか?** =ここから明らかな '= 'と' 'IN'の大きな違いかどうか(http://stackoverflow.com/質問/ 3416076/this-select-query-takes-180-second-finish/3417098#3417098)が修正されました。Mark Byerさんの答え私はそこにあるコメントにリンクしていますが、これはバージョン6.0まで修正される予定ではないと言います –

0

質問には明確な答えはありません。実際には、テーブルのインデックスと、使用しているDBMSが使用できるかどうかによって異なります。私はININNER JOINと比べて実行時間を短縮し、INNER JOINがより速い場合のインスタンスを持っています。

逸話例(ただし、SQL Serverを使用して):

私は、共通のフィールドを使用して、通常のテーブルに一時テーブルに参加しました。実行計画は、実行計画を見たときに2つのテーブルの間にHASH JOINを示しました。実行時間は2秒aproxでした。 INNER JOININに変更してsubselectとすると、ハッシュジョインが消え、実行時間が1秒に短縮されました。現在、メインテーブルのインデックスを使用していました。

0

投稿した2つのクエリが異なる結果を生成することがあります(JOINで2番目の行が最初の行よりも多く返される可能性があります)。そのため、パフォーマンスを比較するのは正しくないと思います。

+0

あなたは正しいです。私はちょうど異なる結果を避けるために唯一のフィールドの区別を入れました。 – Seeker

+0

この場合、2番目の(JOINの場合)が少し悪くなる可能性があります(オプティマイザがスマートに移動していないと、DISTINCTをサブクエリに移動できません – a1ex07