.NET 执行 SQL 查询,Active Monitor 显示多行相互阻塞

Hik*_*ari 7 sql-server optimization ado.net activity-monitor sql-server-2014

我使用 .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
Run Code Online (Sandbox Code Playgroud)

当我查看 Active Monitor 时,有数十行引用相同的操作。它们都具有相同的session_id,其中一些具有正在运行的任务状态,并且大多数处于暂停状态。其中一些具有 LastWaitTime CXPACKET,大多数具有PAGEIOLATCH_SH.

我还在 SQL Server 上运行了一个查询,并且在 Active Monitor 上发生了相同的行为。

也许这是它的正常行为,但奇怪的是 SELECT 操作会创建多行并像这样阻塞自己。知道是什么原因造成的吗?

Geo*_*ios 15

同一 SPID 的活动监视器中的多行意味着您的查询已被选择跨多个线程并行执行。

坚果

Activity Monitor 上的每一行实际上代表一个ECID,而不是一个SPID

活动监视器仅暴露出SPID柱(session_id),但在露出的附加的列sys.sysprocesses称为ECIDË xecution Ç ontext ID) -这是对查询被利用的每个线程的唯一标识符。

sysprocesses系统视图已过时,但可以通过另一个名称(找到ECIDexec_context_id的)sys.dm_os_tasks视图(以及其它任务相关的视图)。

这是一个示例查询,它捕获与在特定会话中运行的查询相关联的所有执行上下文 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;
Run Code Online (Sandbox Code Playgroud)

在 SQL 2016 中,两个新列被添加到sys.dm_exec_requests -DOP并且parallel_worker_count- 这些可用于检查请求是否并行运行。

另一个需要注意的关键项目是CXPACKET等待本质上是一个并行等待——这本身就告诉我们查询使用了多个线程。

PAGEIOLATCH_SH是一个等待,表明这些线程正在将数据从磁盘读取到内存中。