1

私はクエリを作成しており、SQL Profilerトレースを分析して、クエリのパフォーマンスと速度を監視しています。

これを行っているときに、同じテーブルで3つの異なるselectを実行した場合、WHERE句にORを付けて1つのselectにグループ化して実行した場合よりもはるかに高速であることに気付きました。

A)

SELECT * FROM navigation_trees nt  INNER JOIN contents c ON c.navigation_tree_id = nt.id WHERE nt.id = @NodeID

SELECT * FROM navigation_trees nt INNER JOIN contents c ON c.navigation_tree_id = nt.id WHERE nt.id = @ParentID

SELECT * FROM navigation_trees nt INNER JOIN contents c ON c.navigation_tree_id = nt.id WHERE nt.id IN (SELECT id FROM @ChildrenIDS)

B)

SELECT * FROM navigation_trees nt  INNER JOIN contents c ON c.navigation_tree_id = nt.id 
    WHERE 
        nt.id = @NodeID OR
        nt.id = @ParentID OR
        nt.id IN (SELECT id FROM @ChildrenIDS)

そして、これが2つのクエリのプロファイラー測定値です。

CPU | Reads | Writes | Duration(ms)

A) 15 | 1095 | 0 | 26

B) 531 | 456139 | 0 | 541

光を当てることができますか?

どうもありがとう。

4

2 に答える 2

3

3つの選択は、3つの選択だけです。3つの条件を持つ選択は、OR実際には選択に加えて、重複を削除するための追加コストが加わります。

重複が発生しないことが確実な場合は、UNION ALLではなくを使用することを検討してORください。またはもちろん、それは非常に一般的なアドバイスです。パフォーマンスのためだけにクエリを調整する場合は、常に実行プランを参照して、特定のアドバイスがシナリオに適用されることを確認してください。

于 2012-06-21T12:23:19.673 に答える
2

私はDavidに同意しますが、コード例を入れたいと思いました。それらのOrはおそらくキラーです。私が新しい開発者に教える基本的なルールは、あなたが必要な場合、またはあなたが組合を必要とする場合です。これは、フィルターの初期フィルターの他の基本的なルールと頻繁に相関します。オプティマイザーはデータを削減するためのより適切なルートを確認できるため、すべての結合でフィルター処理するクエリは、where句で実行されるフィルターよりも高速であることがよくあります。

クエリはこのように機能するか、他のUnionAllが必要になる場合があります。

Select
    *
From
(
    SELECT * 
    FROM 
        navigation_trees nt  
    WHERE 
        nt.id = @NodeID 

    union 
    SELECT 
        * 
    FROM 
        navigation_trees nt  
    WHERE 
        nt.id = @ParentID 

    union 
    SELECT 
        * 
    FROM 
        navigation_trees nt  
    WHERE
        nt.id IN (SELECT id FROM @ChildrenIDS)

) nt

INNER JOIN 
    contents c 
ON 
    c.navigation_tree_id = nt.id 
于 2012-06-21T12:40:53.080 に答える