2012-05-03 3 views
0

私は多くのフィールドの1つにマッチする履歴エントリのテーブルのレコードと一致する新しいエントリのテーブルのレコードを検索するためにクエリに取り組んでいます。言い換えれば:いくつかの潜在的な条件に一致するクエリ:適切な設計?

次のようにこのクエリの

マイSQLです "ショーcurrent.id = archive.idまたはcurrent.name = archive.nameまたはcurrent.address = archive.addressは、すべてのレコード"

SELECT current.id, current.name, current.address FROM current 
INNER JOIN archive 
ON 
    current.id = archive.id OR 
    current.name = archive.name OR 
    current.address = archive.address 

私が実行すると、それは時間がかかります。これはデータの最初の読み込み時です。アーカイブには常に300,000件のレコードが保存されますが、現在のレコードは500〜40,000の間で変動します。

このクエリを作成するより良い方法はありますか?または、私の質問はしっかりしていますが、潜在的に問題となっている基礎データベースはありますか?

SELECT current.id, current.name, current.address 
FROM current 
INNER JOIN archive 
ON 
    current.id = archive.id 

UNION 

SELECT current.id, current.name, current.address 
FROM current 
INNER JOIN archive 
ON 
    current.name = archive.name 

UNION 

SELECT current.id, current.name, current.address 
FROM current 
INNER JOIN archive 
ON 
    current.address = archive.address 

このクエリはにあなたをできるようになる。(それは非常に大きい場合、特にアーカイブテーブルの上に)おそらく助け、代わりにこれをしようと、各テーブル内の問題の3つのフィールドにインデックスを作成する

答えて

4

フィールドを個別に索引付けします(これを行う必要があります)。その結果、索引が小さくなり、全体的なパフォーマンスが向上します。

結合条件でORを使用すると、クエリオプティマイザが実際には最適化されない可能性があります。 UNIONは高価ですが、照会時間が参加に費やされる可能性が高くなり、単純化すると多くの作業に役立ちます。

+0

また、UNION ALLの一部としてSQL Serverが重複を除外する必要がないように、UNION ALLを使用することもできます。あなたは、事実の後に欺瞞を常に除外することができます。 –

+0

質問:インナージョインのヘルプの代わりに「存在する場所」がありますか? アーカイブからの値が取得されないので...同じ実行計画ですか? –

+0

@RaphaëlAlthausあなたは、私の答えのように一緒に連合する一連の '存在するもの 'を意味するのか、' OR'条件を持つ単一の '存在するもの'を意味しますか?前者の場合、それは私の答えと同じように動作するはずです。後者の場合、私はそれがOPごとに遅くなると思います。 –

関連する問題