2011-02-09 5 views
0

2つのテーブルを比較するとスピードに問題があります。 次の表があるとします。2つのテーブルを比較すると、既存の "id"が見つかりません

14,000レコードを

名(VARCHAR)今、私が欲しい、JOIN_ID(INT)

表B 54209レコードの

second_name、JOIN_ID(INT)

テーブルAに存在する行を見つけますが、Bにはjoint_idで接続されていません ランダム(ソート順)

私は次のことを試してみました:

SELECT a.name , b.second_name 
    FROM a 
    LEFT OUTER JOIN b ON a.joint_id = b.joint_id 
    WHERE b.joint_id IS NULL 
    LIMIT 0,10 

クエリが年齢を取り、サーバーをめちゃくちゃされているので、私の質問があります。

これを行う方法はありますか?

EDIT:私はRAND()を削除しましたが、これは別の方法で解決できます。 しかし、私はまだ同じ問題があります。 以下の提案を試し、クエリ時間を改善できるかどうかを確認します。

+1

テーブルにインデックスがありますか? –

+0

''選択するa.nameなどを実行する ''を実行します。 Mysqlは、クエリの実行に役立つインデックス(もしあれば)を表示します。 –

+1

なぜORDER BY RAND()を使用していますか?大きなテーブルでは非常に効率が悪いですか? –

答えて

3

注意bが存在しない場合、b.second_name => NULLなので、2番目の列には固定値のNULLを与えました。 cruxの問題は、ORDER BY RAND()は、各レコードに対してrand()を置くためにフルスキャンが必要であるということです。あなたはテーブルスキャンを避けることはできません。

SELECT a.name , NULL AS second_name 
FROM a 
WHERE NOT EXISTS (Select * from b WHERE a.joint_id = b.joint_id) 
ORDER BY RAND() 
LIMIT 0,10; 

テーブルaのIDを持っていると仮定すると、テーブルaのすべての列をドラッグする必要がなくなるため、時間を短縮できます。 http://dev.mysql.com/doc/refman/5.0/en/order-by-optimization.html

SELECT a.name , NULL AS second_name 
FROM a 
WHERE a.ID in (
    select id from a 
    WHERE NOT EXISTS (Select * from b WHERE a.joint_id = b.joint_id) 
    ORDER BY RAND() 
    LIMIT 0,10) 
+0

これはjoinを使用するのと同じパフォーマンスを発揮します –

+1

+1 @K Ivanov:NOT EXISTSのパフォーマンスが向上すると思います。参照:[左外部結合対NOT EXISTS](http://sqlinthewild.co.za/index.php/2010/03/23/left-outer-join-vs-not-exists/) –

+0

私のことを覚えておいてくださいブログの投稿(Joeが参照している)は、MySQLではなく、MS SQL Server用です。 MySQLがどのように結合を処理し、存在するかについては結論を出す必要はありません – GilaMonster

2

すべての行でNULLとしてショーをb.second_nameませんか?

(EXPLAIN付き)インデクスの使用を確認するだけでなく、あなたもこのバージョンを確認することができます

SELECT a.name 
    FROM a 
    WHERE a.joint_id NOT IN (SELECT b.joint_id 
           FROM b 
          ) 
    ORDER BY RAND() 
    LIMIT 0,10 

注意:b.joint_idはNOT NULL属性を持っていない場合は、他のものの例をEXISTSと同様に、NOT INを振る舞います書きました。

ただし、b.joint_idがNullableの場合、この回答は使用しないでください。間違った結果が出るでしょう。

+0

+1 –

関連する問題