2016-05-27 19 views
2

同じデータを別の列で参照する必要がある場合は、常に複数の結合を使用しています。このように:同じテーブルを複数回クエリする

select 
    a.ContactName 
    ,b.ContactName 
    ,c.ContactName 
from 
    OrderBase as o 
    left join ContactBase as a on o.contactid1 = a.ContactId 
    left join ContactBase as b on o.contactid2 = b.ContactId 
    left join ContactBase as c on o.contactid3 = c.ContactId 

私はこれが非常に非効率であると常に考えていました。 3回のルックアップのためにテーブルを3回ロードする。これを行うより効率的な方法はありますか?私はコードの記述ではなく、リソースの使用を意味します。 これに対処するSQL Serverのそれ以降のバージョンに実装された良いツールはありますか?

+1

正しいインデックスを使用している場合は、これが最善のアプローチである必要があります。 – Shnugo

+0

連絡先1,2および3に3つの列が必要です。その結果を得る他の方法はありません。あなたのデータベースはどれくらい大きいですか?それが十分に大きくなければ、なぜこれが効率的ではないと思うのですか?パフォーマンスの問題がある場合は、この特定のクエリに対してschema_bindingビューを使用できます。それはディスクストレージを使用します。ところで、私はあなたのContacBaseテーブルが大きくてはならないと思います。 ContactBaseテーブルが大きい場合、インデックスを追加するとパフォーマンスが向上します。そうしないと、多くの機能が改善されません。 – FLICKER

+0

OrderBaseはcontactName1、contactName2、contactName3を追加し、OrderBaseが更新された場所にストアできます。その後、参加する必要はありません... – daniel

答えて

1

最初のコメントは、同じ値を複数の列に格納することは、しばしば疑わしいパターンであることです。多くの場合、このようなデータ構造は、「OrderBase」ごとに1行、「ContactId」ごとに1つずつのジャンクション表を使用する方が適しています。ジャンクション・テーブルは必ずしも最良の解決策ではありませんが、しばしば最適です。

クエリのとおり:これは、具体的ContractBase(ContactId, ContactName)にインデックスを望んでいる

select a.ContactName, b.ContactName, c.ContactName 
from OrderBase as o left join 
    ContactBase a 
    on o.contactid1 = a.ContactId left join 
    ContactBase b 
    on o.contactid2 = b.ContactId left join 
    ContactBase c 
    on o.contactid3 = c.ContactId; 

。この目的のためにleft joinを使用することは全く合理的です。

このインデックスでは、インデックスがインデックスをカバーしているため、クエリのすべての列がインデックスに含まれているため、元のデータページはクエリによって必要なものでもありません。索引を複数回ロードすることについて心配する必要はありません。インデックス(またはテーブル)はですが、論理的にはが3回ロードされますが、ページキャッシュと呼ばれるものはおそらくページをメモリに保持するため、後続のロードは非常に高速になります。

+0

私は独学ですので、データベースエンジンの内部の仕組みについてはまだ専門家はいません(まだ)。これを行うための「より良い」方法はないようです(まだ)。しかし、私はいつも学んでいるので、これについて詳しく説明できますか?論理的にロードされたインデックスは、どのように膨大な量のデータを処理しますか?データを無制限にキャッシュできますか?私が150列に加わり、何百万もの行を持っているなら、これをやるのが最良の方法です(書き込みの悪夢を考えないでください。 – Sweetspot

+0

@ Sweetspot。 。 。問題が発生するまで、パフォーマンスの問題を心配するべきではありません。このように3つの 'left join'を実行することは、インデックスが正しく設定されていることを前提として、問題ではありません。 –

関連する問題