2012-04-11 17 views
1

パフォーマンスを向上させるために、結合後のネストされたクエリを使用して次のクエリを書き直すように言われました。本当ですか?もしそうなら、それを書き換える方法は?これをネストされたクエリとして書き直すにはどうすればよいですか?

SELECT distinct A.Company_Name,C.Outlet_Name, 
     C.Outlet_FCE_ID,D.Usergroup_Name 
FROM company A, PURCHASE_INVOICE B, 
     Outlet C, User_Group D,CT_USER E 
WHERE A.Company_ID = B.Company_ID AND B.Outlet_ID = C.Outlet_ID 
    AND B.Company_ID = C.Company_ID AND B.Username = E.Username 
    AND E.Usergroup_ID=D.Usergroup_ID 

ここはテーブルの構造です。

enter image description here

+1

なぜネストされたクエリは通常、ジョインよりも優れているか悪いのですか?それは本当に多くのものに依存します。実際の問題は、あまりにも多くのデータを選択してから、「別個」を使用して重複を削除しているという事実に関連している可能性があります。なぜあなたは「別れた」必要がありますか?外部キーなどの関連するすべてのインデックスを表示できますか? –

+2

私はこれについても好奇心が強いです。私の経験上、インデックスが正しく設定されていると仮定すると、オプティマイザは何よりも結合を最大限に活用しようとしています。 – moleboy

+0

実行が遅い場合は、実行計画をチェックし、SQLプロファイラを実行します(ただし、プロダクションボックスに対しては使用しないでください:)。いったん把握したら、列の索引をDBAに追加することをお勧めします。しかし、ネストされたクエリのパフォーマンスに対するジョインに関する他のコメントに同意します。 – Eugene

答えて

0

:-)です。私はこのように好きではありませんが、ここで私たちは行く...

SELECT distinct 
     (SELECT Company_Name 
      FROM  dbo.COMPANY 
      WHERE  Company_ID = p.Company_ID 
     ) AS 'CompanyName' , 
     (SELECT Outlet_Name 
      FROM  dbo.OUTLET 
      WHERE  Company_ID = p.Company_ID 
        AND Outlet_ID = p.Outlet_ID 
     ) AS 'OutletName' , 
     (SELECT Outlet_FCE_ID 
      FROM  dbo.OUTLET 
      WHERE  Company_ID = p.Company_ID 
        AND Outlet_ID = p.Outlet_ID 
     ) 'OutletFCEID' , 
     (SELECT Usergroup_Name 
      FROM  dbo.USER_GROUP 
      WHERE  Usergroup_ID IN (SELECT Usergroup_ID 
             FROM  CT_USER 
             WHERE  Username = p.UserName) 
     ) 'UsergroupName' 
FROM dbo.PURCHASE_INVOICE p 
1

オプティマイザは、この権利を取得する必要がありますが、この1に対する元のクエリのパフォーマンスを比較することもできます。

select distinct 
    c.company_name, 
    o.outlet_name, 
    o.outlet_fce_id, 
    ug.usergroup_name 
from company c 
    inner join (select distinct company_id, outlet_id, username from purchase_invoice) i on c.company_id=i.company_id 
    inner join outlet o 
     on i.outlet_id = o.outlet_id 
     and i.company_id = o.company_id 
    inner join ot_user u  on b.username  = e.username 
    inner join user_group ug on u.usergroup_id = d.usergroup_id 

purschasesテーブル上の異なるが、いくつかの作業を排除することができますしかし、私はそれがたくさんあるなら、私は倍増します。

purchase_invoice (username, outlet_id, company_id)のインデックスは何ですか?これはテーブル上にcovering indexになるため、速度を上げることができます。結合は索引を見るだけで済み、実際の表を読み飛ばすことができます。それはテーブルが広い場合に役立ちます。

インデックスの列の順序にも注意してください。ct_userにも多くの行があり、Usernameにクラスタード・インデックスがあることを推測しています。こうすると、インデックスとct_userの両方がユーザー名でソートされ、2つの大きなテーブルを結合するためにmerge joinが許可されます。

また、user_groupの場合はc fr companyやugのようなテーブルでは、結合構文と意味のある別名を使用してください。それはデータベースには関係ありませんが、人間があなたのコードを読もうとしているときには致命的に役立ちます。 はまた、allcapsはYOUR SCREAMING ALL TIMEのように見えますが、多分それは私が自分の質問に答えてみましょうちょうど私

GJ

関連する問題