2017-11-16 22 views
0

SQL SELECTサブクエリ

User   List 
------  ------ 
userId (PK) listId (PK) 
fullName  description 
       addedById (FK with userId in User table) 
       modifiedById (FK with userId in User table) 

fullNameユーザーテーブルから引き出す必要があります。

このクエリが機能し、必要なデータが表示されます。しかし、このクエリを構築するより良い方法があるかどうかはわかりません。主にパフォーマンスの問題が原因で、メインの選択クエリ内に複数のサブ選択クエリがあることに熱心ではありません。

select t1.[description], 
    t1.addedById, 
    t1.modifiedById, 
    (select fullName from dbo.User where userId = t1.addedById) as [AddedByUser], 
    (select fullName from dbo.User where userId = t1.modifiedById) as [ModifiedByUser] 

from dbo.List t1 

誰がクエリの改善を提案し、またはあるとして維持するために助言することができれば、私は本当に感謝します。

ありがとうございました。

+2

代わりにLEFT JOINを実行してください。 – jarlh

+3

'userId'にインデックスがあると仮定しても、クエリは正常です。別のアプローチはLEFT JOINです。どちらのアプローチでも、パフォーマンスはかなり似ているはずです。 –

+1

SOのトピックはありません。 CodeReviewに投稿することをお勧めします。 –

答えて

1

より標準的なSQLの方法は次のようになります。

SELECT t1.description, 
    t1.addedById, 
    t1.modifiedById, 
    add.fullName AS [AddedByUser], 
    mod.fullName AS [ModifiedByUser] 
FROM dbo.List t1 
LEFT JOIN dbo.User add 
    ON add.userId = t1.addedById 
LEFT JOIN dbo.User mod 
    ON mod.userID = t1.modifiedById 

しかし、私はこれがあなたのクエリに同一の実行、おそらく同じ実行計画を持っています疑い。この方法の唯一の本当の利点は、展開が容易だということです。たとえば、Userテーブルから新しい列を追加する場合は、これは簡単です。

@Gordonは、参加しているフィールドにインデックスがある場合、パフォーマンスは良いはずです。

+0

この代替アプローチは非常に便利です。私が参加しているフィールドにはインデックスがあり、どちらのアプローチとも何の違いも気づいていません。 – tgriffiths

1

同じテーブルでダブルジョインしても気になるのですか?リンクされたサブクエリを作成する代わりに、それを実行するのが好ましい方法です。

私はあなたがPKと両方のFKにインデックスを持っていると仮定しています。

最小化できるのは、結合された行の数を減らすことだけです。 左の内部結合を使用するか、where節でフィルタリングを行うことができます。結合で使用する両方のキーがnullでないことが必要です。

私は両方の例を書くことができますが、これは自明です。

他の市長が行うことは、ユーザーからの値をPRESELECTすることです。たとえば、ユーザーがたくさんいる場合は、どちらかのロールにしか参加できないことがわかります。そして、あなたがリストしていないユーザのいくつかのカラムで、そのカラムにインデックスがあればさらに優れたものをフィルタリングできます。

これらのユーザーのみを事前に選択してから、選択結果に参加することで利益を得ることができます。両方を事前に選択できる場合はテンポラリテーブルを使用するか、テーブル全体に参加する代わりにスポットを選択します。これが関連するようにここで扱っている番号についてはわかりません。