2012-04-22 20 views
-1

私はSOItems と呼ばれる特別オファー項目のテーブルSpecialOffersとテーブルを持っていると私はそれはそう最初私は、このやった場合、私は、特定の項目のための特別なオファーを取得したい:複数のSQLクエリまたは結合?

IF EXISTS(SELECT * FROM SOTtems WHERE ItemType = 2 AND Itemid = @id) 
BEGIN 
     INSERT INTO #SO 
     SELECT * FROM SpecialOffers so 
     INNER JOIN SOItems soi ON so.Id = soi.SpecialOfferID 
     WHERE soi.ItemType = 2 AND soi.Itemid = @id 
END 

しかし、その後取り除くために

DECLARE @specialOfferID INT 

SET @specialOfferID = (SELECT SpecialOfferID FROM SOTtems WHERE ItemType = 2 AND Itemid = @id) 

IF @specialOfferID IS NOT NULL 
BEGIN 
    INSERT INTO #SO 
    SELECT * FROM SpecialOffers so 
    WHERE ID = @specialOfferID 
END 

ので、より多くのSQLクエリを実行するか、この例のためにと一般

に参加使用するためのパフォーマンスのために、より効率的かつ優れている:INNERの私はそれがパフォーマンスのために良いでしょうと思ったので、私はこれをしなかったのJOIN

注:ストアドプロシージャに私は私はuがオプティマイザは以上のものですので、この手の最適化は、不要と思われる

おかげ

答えて

1

:)を尋ねた理由は、この6倍以上に持って書いていますこれを処理する能力がある。

両方をSSMSに入れて一緒に実行し、実行計画の相対コストを調べることができます。

通常、結合を避けることは、最適化の第一歩ではありません。

私の最初のステップは、通常、インデックス作成戦略を見て、基本的なインデックスを削除していないことを確認してから、実行計画を見て、目障りな問題がないかどうかを確認することです。

次に、パフォーマンスの問題が実際に発生するまで、そして実際にパフォーマンスの問題を引き起こしていることを理解した後でのみ、最適化は行われません。

私は実際にだけにそれを単純化する:

INSERT INTO #SO 
SELECT * 
FROM SpecialOffers so 
INNER JOIN SOItems soi 
    ON so.Id = soi.SpecialOfferID 
    AND soi.ItemType = 2 
    AND soi.Itemid = @id 

をそれはあるん - これは、そうでない場合は何も挿入しませんので、内部結合の存在のためのチェックが冗長であることを意味 - 何のチェックや他の何かをEXISTS 。これは、条件が変更された場合に条件を複製する必要がなく、結合内のコードが誤って変更される可能性がなくなるため、メンテナンス可能なコードをある意味で作成します。一方、結合が変更されると、それはより深刻な影響を与える可能性があります。

EXISTSチェックを使用しなくても、これをWHEREバージョンとして書き込むことができます。

通常、コードが少ないほど、バグが隠れる場所が少なくなります。

+0

おかげさまで私はあなたに同意しますが、パフォーマンスの問題が発生するまでは最適化しません。私が同意しない場合は、最初にコードを良く書くと将来的にパフォーマンスの問題が発生しません。 – AlaaL

+0

を@TheDarkLordで最適化する必要はありません。コードはまず正しく動作し、維持可能であり、基本的なベストプラクティスを満たしている必要があります。それ以降のすべてが最適化です。しかし、あなたは正しいです、SQL Serverの多くの(14、多分?)年後、私の基本的なベストプラクティスの定義は、それ以上の最適化を避けるのに十分です。 –

+0

ご協力ありがとうございます。 – AlaaL

1

Management Studioのウィンドウで2つのクエリをすべて通過し、クエリの実行計画を表示します。それは起こっていることを正確に教えてくれるでしょう。

ほとんどの場合、パフォーマンスの差はごくわずかです。秒をやや速くするのはIF EXISTS(...)がないということですが、一方で結果はキャッシュされるため、その差はまだ小さいです。

別のことは、最初のクエリを使用して#SOテーブルにデータを追加していることです。 SELECT *を使用しているので、必要以上のデータが得られます。たとえば、フィールドSOItems.SpecialOfferIDSpecialOffers.Idの両方が含まれますが、それらは常に同じであることがわかります。返されるフィールドを指定して、必要以上にフェッチしないようにします。

+0

はい、本当に私は実際のコードでSELECT *を使用していませんが、ここに書き込むので、フィールドの名前を書く必要はありません:) – AlaaL

+0

@TheDarkLord:聞いてよかったです。 :) – Guffa

関連する問題