1

次のテーブル構造がある場合...

Table 1: BlogPost

PostId |  Name | Text    

Table 2: Tags

TagId  | Tag    

Table 3: BlogPostTag

PostId | TagId

そして、次のストアドプロシージャ...

CREATE PROCEDURE SearchBlogPosts

    @tagstring nvarchar(max),

AS
BEGIN

    DECLARE @searchTags TABLE (Tag varchar(50));

    IF @tagstring IS NOT NULL AND @tagstring <> ''
        BEGIN
            INSERT INTO @tags SELECT s AS tag FROM dbo.Split(',',@tagstring);
        END

    SELECT * FROM BlogPost b
        JOIN BlogPostTags bt on bt.PostId = b.PostId    
        JOIN Tags t on t.TagId = bt.TagId
        JOIN @searchTags st ON st.Tag = t.Tag
            ...
        (Other Joins and where clauses may exist below here)
END

... @tagstring が null または空白の場合、タグ テーブルの結合を除外できる最も「パフォーマンスの高い」方法は何ですか?

4

3 に答える 3

2

条件付き結合を指定する唯一の方法 (そして最善の方法) は、個別のクエリを使用することです。

IF @tagstring IS NOT NULL AND @tagstring <> '' 
BEGIN
    SELECT * FROM BlogPost b 
        JOIN BlogPostTags bt on bt.PostId = b.PostId     
        JOIN Tags t on t.TagId = bt.TagId 
        JOIN @searchTags st ON st.Tag = t.Tag 
END
ELSE
BEGIN
    SELECT * FROM BlogPost b 
        JOIN BlogPostTags bt on bt.PostId = b.PostId     
        JOIN Tags t on t.TagId = bt.TagId 
END

SQL は宣言型データ アクセス言語であり、アプリケーションの命令型処理言語ではありません。宣言するすべてのクエリは、すべてのケースで機能するアクセス パスを作成する必要があります。クエリに条件付きロジックを含めることは、最悪の場合です。アクセス プランは、プランの作成時に条件が true か false かを判断できないため、通常は考えられるすべてのデータをスキャンすることになります。

于 2010-10-29T22:54:44.310 に答える
0

左結合を指定してもパフォーマンスが低下するとは思いません (@tagstring が null または空白の場合、@searchTags は空であると想定しています)。

または、@searchTags をタグに結合することでパフォーマンスが低下したくないですか?

あなたの例では、 @searchtags のデータがどこから来たのかははっきりしていません。

LEFT JOIN Tags t on t.TagId = bt.TagId AND @tagstring is not null AND @tagstring <> ''

サーバーは、その条件が存在する状態で参加を試みないように十分にスマートでなければなりません。いずれにせよ、重大なパフォーマンスの低下を引き起こすものではないと思います。

何らかの理由で結果に列がまったく表示されないようにする場合は、2 つの異なるクエリを使用した IF...ELSE ブロックが最も簡単な方法です。

于 2010-10-29T22:36:30.407 に答える
0

@tagstring が null または空白の場合、クエリを実行しないことで得られる最高のパフォーマンスが得られると思います。すべての内部結合と @searchTags に行がないため、行が返されることはありません。

したがって、true ブロックの場合、SELECT ステートメントを IF ステートメントに移動できます。

于 2010-10-29T22:54:16.123 に答える