我们的 SQL 被配置为使用最多 704 个线程,有时我们会收到警告说只剩下 10 个线程,所以我无法理解 SQL 是否保持线程打开,因为再次创建新线程很昂贵。
所以我的问题是
如何知道线程是否可用于新请求或当前正忙于其他请求。
我正在尝试
task_address
从 sys.dm_exec_requests 与 sys.dm_os_tasks 链接,worker_address
如下所示select * from sys.dm_exec_requests ec join sys.dm_os_tasks tsk on tsk.task_state=ec.task_address join sys.dm_os_workers wrk on wrk.worker_address=tsk.worker_address
我没有看到任何输出,这是否意味着我可以假设所有线程都是空闲的
- 目前下面是我的工作线程的状态,这个暂停是什么意思?。我可以看到超过 500 个处于暂停状态。我没有看到任何阻塞
4.我可以使用下面的查询来发现我有工作线程饥饿吗
select status from sys.dm_Exec_requests
如果状态为待处理,我可以假设 SQL 正在等待新的工作线程吗
- 目前我看到一个会话,在 sysprocesses 中有超过 250 行,当我查询时
sys.dm_os_Waiting_tasks
,我可以看到超过 2186 行,其中 90% 用于同一个会话。所以我的问题是查询如何跨越这么多线程
我会使用以下查询获得可用的工人人数,这是正确的吗?
select ( select max_workers_count from sys.dm_os_sys_info ) - ( select sum(active_workers_count) from sys.dm_os_Schedulers )
您可以使用 DMV sys.dm_os_schedulers来获取此信息。您必须参考的专栏是
work_queue_count
。根据 BOL,这意味着您可以使用以下查询来检查所有在线调度程序的等待任务数
我不确定您要达到的目标,但以下是我从该博客中得到的
挂起是正在等待某些资源并且当前不活动的线程。等待可以是 I/O、网络等。有关详细信息,请参阅我分享的博客。
不,这不是正确的查询。
停止使用 sys.sysprocesses 是旧视图,MS 不建议使用它。而是使用
sys.dm_exec_requests
您可以使用 DMV sys.dm_os_scheduler 获取每个调度程序的工作线程数
我做了一些测试,发现对我的问题的澄清很少。在此处添加它们。
1.如何知道一个线程是否可用于新请求或当前正忙于其他请求。
SQL server 将根据这个公式分配线程,同样可以在 sys.dm_os_sys_info 中找到,SQL 默认情况下从初始线程开始,并将根据负载不断增加线程到最大线程限制。要注意的是 SQL 不会杀死线程一旦创建,因为再次创建它们的成本很高。
在我的情况下,我们曾经收到警告说只有 1o 个线程可用,但我无法弄清楚是否有任何线程可用于服务请求。
使用基于此博客的 Ostress 工具进行的小测试也是如此,发现可以使用以下查询在任何时间点找到可用线程
2.我正在尝试将 sys.dm_exec_requests 中的 task_address 与 sys.dm_os_tasks 和工作地址链接,如下所示
抱歉,如果我的问题不清楚,但我想检查查询是否并行运行。
任何并行查询都会在 sys.dm_os_tasks 加上 sys.sysprocesses 中有一个条目,因此要运行哪些查询并行运行,我们可以使用下面的 dmv。
3.目前下面是我的工作线程的状态,这个挂起是什么意思?。我可以看到超过 500 个处于挂起状态。我没有看到任何阻塞
由于多种原因,线程可能会被挂起,我检查了等待类型并且所有 spid 都在等待 CXpacket
4.我可以使用下面的查询来发现我有工作线程饥饿吗
要知道您是否遭受工作线程饥饿,请使用以下查询。
目前我看到一个会话,在 sysprocesses 中有超过 250 行,当我查询 sys.dm_os_Waiting_tasks 时,我可以看到超过 2186 行,其中 90% 用于同一个会话。所以我的问题是查询如何跨越这些许多线程
根据我的理解,SQL 在使用并行性时会产生许多线程(如果它们可用),并且 SQL 跨度的线程数不限于 CPU 内核数,这就是我的情况,所以我们将尝试检查为什么这个查询成本是被 SQL 视为高,并将对此进行测试。
感谢在线资源,我有一个误解,即当一个线程被异步 i/O 阻塞时,我认为 SQL 会尝试将这项工作卸载到 OS 线程,但事实并非如此