web-dev-qa-db-ja.com

.NETはSQLクエリを実行し、アクティブモニターは複数の行が互いにブロックしていることを示します

私は.NETを使用してSQL Server 2014でSQL操作を実行します。使用するコードは次のとおりです。

using(SqlConnection conn = new SqlConnection(connectionString)){
    //https://stackoverflow.com/questions/1880471/capture-stored-procedure-print-output-in-net
    conn.InfoMessage += new SqlInfoMessageEventHandler(logSqlMessages);
    conn.Open();
    using(SqlCommand stmt = new SqlCommand{
        Connection = conn,
        CommandText = sql,
        CommandTimeout = 30000 // The time in seconds to wait for the command to execute. The default is 30 seconds.
        //,CommandType = CommandType.StoredProcedure
    })
    {
        affectedRecords = stmt.ExecuteNonQuery();
    } // using stmt
} // using conn

アクティブモニターを見ると、同じ操作を参照する数十の行があります。それらはすべて同じsession_id、それらのいくつかは実行中のタスク状態を持ち、それらのほとんどは一時停止されています。それらのいくつかはLastWaitTime CXPACKETを持ち、ほとんどはPAGEIOLATCH_SH

SQL Serverでもクエリを実行しましたが、Active Monitorでも同じ動作が発生しました。

多分それはそれの正常な動作ですが、SELECT操作が複数の行を作成し、そのようにそれ自体をブロックするのは奇妙です。何がそれを引き起こしているのか考えていますか?

7
Hikari

同じSPIDのアクティビティモニターの複数の行は、クエリが複数のスレッドで並列に実行されるように選択されていることを意味します。

NUTS

アクティビティモニターの各行は、実際には1つのECIDではなく1つのSPIDを表します。

アクティビティモニターはSPID列(session_id)のみを公開しますが、ECIDと呼ばれる sys.sysprocesses で公開される追加の列があります([〜#〜] e [〜#〜]実行[〜#〜] c [〜#〜 ]ontext[〜#〜] id [〜#〜])-これは各スレッドの一意の識別子ですクエリは利用されています。

sysprocessesシステムビューは非推奨ですが、 exec_context_id ビューで別の名前(sys.dm_os_tasks)でECIDを見つけることができます(同様に他のタスク関連のビューとして)。

以下は、特定のセッションで実行されているクエリに関連付けられているすべての実行コンテキストIDと、それらが待機しているものをキャプチャするサンプルクエリです。

SELECT 
    dot.session_id,
    dot.exec_context_id,
    dot.task_state,
    dowt.wait_type,
    dowt.wait_duration_ms,
    dowt.blocking_session_id,
    dowt.resource_description
FROM sys.dm_os_tasks dot
    LEFT JOIN sys.dm_os_waiting_tasks dowt
        ON  dowt.exec_context_id = dot.exec_context_id
            AND dowt.session_id = dot.session_id
WHERE dot.session_id = 51
ORDER BY exec_context_id;

SQL 2016では、2つの新しい列が sys.dm_exec_requests に追加されました-DOPおよびparallel_worker_count-これらは、要求が実行されているかどうかを確認するために使用できます並列かどうか。

注意すべきもう1つの重要な点は、CXPACKETの待機は本質的に並列処理の待機であることです。これだけで、クエリが複数のスレッドを使用していることがわかります。

PAGEIOLATCH_SHは、これらのスレッドがディスクからメモリにデータを読み込んでいることを示す待機です。

15
George.Palacios