我使用 .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
当我查看 Active Monitor 时,有数十行引用相同的操作。它们都具有相同的session_id
,其中一些具有正在运行的任务状态,并且大多数都处于挂起状态。其中一些有 LastWaitTime CXPACKET
,大多数是PAGEIOLATCH_SH
.
我还在 SQL Server 上运行了一个查询,并且在 Active Monitor 上发生了同样的行为。
也许这是它的正常行为,但奇怪的是 SELECT 操作会创建多行并像这样阻塞自己。知道是什么原因造成的吗?
同一 SPID 的活动监视器中的多行意味着您的查询已被选择跨多个线程并行执行。
Activity Monitor 上的每一行实际上代表一个
ECID
,而不是一个SPID
。活动监视器仅公开
SPID
列 (session_id
),但在sys.sysprocesses中公开了一个名为ECID
(执行上下文ID ) 的附加列-这是查询正在使用的每个线程的唯一标识符。系统视图已弃用,但您可以在视图(以及其他与任务相关的视图) 中通过另一个名称 ( )
sysprocesses
找到 ECID 。exec_context_id
sys.dm_os_tasks
这是一个示例查询,它捕获与在特定会话中运行的查询相关的所有执行上下文 ID,以及它们正在等待什么(如果有的话):
在 SQL 2016 中,向sys.dm_exec_requests添加了两个新列-
DOP
并且parallel_worker_count
- 这些可用于检查请求是否并行运行。另一个需要注意的关键项是
CXPACKET
等待本质上是一种并行等待——这本身就告诉我们查询正在使用多个线程。这
PAGEIOLATCH_SH
是一个等待,表明这些线程正在将数据从磁盘读取到内存中。