8

質問とその回答に応じて、いくつかのユーザー ID をフィルタリングするための 2 つのクエリがあります。

シナリオ

クエリ A は (元のバージョン):

SELECT userid
FROM mem..ProfileResult
WHERE ( ( QuestionID = 4
          AND QuestionLabelID = 0
          AND AnswerGroupID = 4
          AND ResultValue = 1
        )
        OR ( QuestionID = 14
             AND QuestionLabelID = 0
             AND AnswerGroupID = 19
             AND ResultValue = 3
           )
        OR ( QuestionID = 23
             AND QuestionLabelID = 0
             AND AnswerGroupID = 28
             AND ( ResultValue & 16384 > 0 )
           )
        OR ( QuestionID = 17
             AND QuestionLabelID = 0
             AND AnswerGroupID = 22
             AND ( ResultValue = 6
                   OR ResultValue = 19
                   OR ResultValue = 21
                 )
           )
        OR ( QuestionID = 50
             AND QuestionLabelID = 0
             AND AnswerGroupID = 51
             AND ( ResultValue = 10
                   OR ResultValue = 41
                 )
           )
      )
GROUP BY userid
HAVING COUNT(*) = 5

「set statistics time on」と「set statistic io on」を使用して、CPU 時間と io パフォーマンスを確認します。

結果は次のとおりです。

CPU time = 47206 ms,  elapsed time = 20655 ms.

Set 操作を使用してクエリ A を書き直し、クエリ B と名付けます。

SELECT userid
FROM ( SELECT userid
        FROM mem..ProfileResult
        WHERE QuestionID = 4
            AND QuestionLabelID = 0
            AND AnswerGroupID = 4
            AND ResultValue = 1
       INTERSECT
       SELECT userid
        FROM mem..ProfileResult
        WHERE QuestionID = 14
            AND QuestionLabelID = 0
            AND AnswerGroupID = 19
            AND ResultValue = 3
       INTERSECT
       SELECT userid
        FROM mem..ProfileResult
        WHERE QuestionID = 23
            AND QuestionLabelID = 0
            AND AnswerGroupID = 28
            AND ( ResultValue & 16384 > 0 )
       INTERSECT
       SELECT userid
        FROM mem..ProfileResult
        WHERE QuestionID = 17
            AND QuestionLabelID = 0
            AND AnswerGroupID = 22
            AND ( ResultValue = 6
                  OR ResultValue = 19
                  OR ResultValue = 21
                )
       INTERSECT
       SELECT userid
        FROM mem..ProfileResult
        WHERE QuestionID = 50
            AND QuestionLabelID = 0
            AND AnswerGroupID = 51
            AND ( ResultValue = 10
                  OR ResultValue = 41
                )
     ) vv;

CPU 時間と経過時間は次のとおりです。

CPU time = 8480 ms,  elapsed time = 18509 ms

私の簡単な分析

上の結果からわかるように、クエリ A は経過時間の 2 倍以上の CPU 時間を持っています。

私はこのケースを検索します。CPU 時間は、CPU がこのタスクを実行している時間の長さであるため、CPU 時間は経過時間よりも短くする必要があると言う人がほとんどです。また、経過時間には I/O 時間やその他の時間コストが含まれます。ただし、1 つの特別なケースは、サーバーに複数のコア CPU がある場合です。ただし、開発用の db サーバーを確認したところ、シングル コア CPU が 1 つあります。

質問1

シングル コア CPU 環境で、クエリ A の経過時間よりも長い CPU 時間を説明するにはどうすればよいですか?

質問2

集合演算を使ってみたら、本当に性能が向上したのでしょうか?

クエリ B の論理読み取りが 280627 であり、クエリ A の 241885 よりも高いため、この質問があります。

Brad McGehee氏は自身の記事で、「クエリによって実行される論理読み取りが少ないほど効率的であり、他のすべての条件が同じであると仮定すると実行速度が速くなります」と述べています。

よりも、クエリ B でさえクエリ A よりも高い論理読み取りを持っていると正しく言いますが、CPU 時間はクエリ A よりも大幅に少なく、クエリ B はパフォーマンスが優れているはずです。

4

2 に答える 2

10

CPU が経過時間よりも大きい場合はマルチコアまたはハイパースレッド CPUを使用しています。

CPU 時間は、SQL Server エンジンがインストールされている場所です。ローカルの Management Studio インストール用ではありません。

論理 IO と CPU については、より低い CPU を使用します。これが頻繁に重複して実行される場合は、最初に CPU リソースが不足します。WHERE EXISTS (UNION ALL) コンストラクトを試して、適切なインデックスがあることを確認します。

編集、コメントの後

  • 計画に並列処理演算子がある = OS と SQL Server から見える複数の論理プロセッサ。したがって、マルチコアまたはハイパースレッドのいずれかです

EXEC xp_msver を試す

于 2011-06-21T04:25:50.427 に答える
2

私の場合、 SQL Server 実行時間: CPU 時間 = 671 ミリ秒、経過時間 = 255 ミリ秒。

CPU 時間は、クエリの経過時間の約 3 倍でした。クエリが並列で処理されたため、CPU の負荷が非常に高くなり、このシナリオでは CPU がボトルネックになる可能性がありました。

SQL Server 2012 は、CPU 負荷の問題を解決します。行ごとだけでなく、一度に行のバッチを処理する反復子が導入されています。

クエリの最適化のために、テーブルに列ストア インデックスを作成することができます-

COLUMNSTORE INDEX idx_cs_colname を dbo.Tablename(feild1,feild2) に作成します。

于 2014-07-22T13:31:16.153 に答える