私は.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操作が複数の行を作成し、そのようにそれ自体をブロックするのは奇妙です。何がそれを引き起こしているのか考えていますか?
同じSPIDのアクティビティモニターの複数の行は、クエリが複数のスレッドで並列に実行されるように選択されていることを意味します。
アクティビティモニターの各行は、実際には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
は、これらのスレッドがディスクからメモリにデータを読み込んでいることを示す待機です。