查找哪个会话持有哪个临时表

SQL*_*IKE 17 sql-server-2005 sql-server tempdb

我们有一个 SQL Server 2005 数据库,临时数据库已满。通过进入 SQL Server Management Studio,我可以看到 tempdb 中的所有临时表。是否可以判断哪个会话持有哪个临时表?理想情况下,一个查询将列出每个会话使用的临时表。

谢谢,

Aar*_*and 19

早在 2007 年,我就要求在 Connect 上内置一些东西。这在 2008 年版本中被拒绝,随后被忽略,直到几年前 Connect 死了。我试图在 SQL Server 的新反馈站点上找到它](该站点也已被终止,但该搜索绝对是垃圾站火。我的请求的标题是“将临时表映射到 session_id 的 dmv”-因为搜索可以only do OR,"map temp table" 返回 118 页的结果。谷歌似乎暗示该项目在他们杀死 Connect 时没有被削减

同时,对于 SQL Server 2005 和 2008,您应该能够从默认跟踪中提取此信息:

DECLARE @FileName VARCHAR(MAX)  

SELECT @FileName = SUBSTRING(path, 0,
   LEN(path)-CHARINDEX('\', REVERSE(path))+1) + '\Log.trc'  
FROM sys.traces   
WHERE is_default = 1;  

SELECT   
     o.name,   
     o.OBJECT_ID,  
     o.create_date, 
     gt.NTUserName,  
     gt.HostName,  
     gt.SPID,  
     gt.DatabaseName,  
     gt.TEXTData 
FROM sys.fn_trace_gettable( @FileName, DEFAULT ) AS gt  
JOIN tempdb.sys.objects AS o   
     ON gt.ObjectID = o.OBJECT_ID  
WHERE gt.DatabaseID = 2 
  AND gt.EventClass = 46 -- (Object:Created Event from sys.trace_events)  
  AND o.create_date >= DATEADD(ms, -100, gt.StartTime)   
  AND o.create_date <= DATEADD(ms, 100, gt.StartTime)
Run Code Online (Sandbox Code Playgroud)

无耻地从这篇 Jonathan Kehayias 博客文章中解脱出来

要确定空间使用情况,您可以进一步增强它以从视图中加入数据,例如sys.db_db_partition_stats- 例如:

DECLARE @FileName VARCHAR(MAX)  

SELECT @FileName = SUBSTRING(path, 0,
   LEN(path)-CHARINDEX('\', REVERSE(path))+1) + '\Log.trc'  
FROM sys.traces   
WHERE is_default = 1;  

SELECT   
     o.name,   
     o.OBJECT_ID,  
     o.create_date, 
     gt.NTUserName,  
     gt.HostName,  
     gt.SPID,  
     gt.DatabaseName,  
     gt.TEXTData,
     row_count = x.rc,
     used_page_count = x.upc
FROM sys.fn_trace_gettable( @FileName, DEFAULT ) AS gt  
JOIN tempdb.sys.objects AS o   
     ON gt.ObjectID = o.OBJECT_ID
INNER JOIN
(
 SELECT [object_id], SUM(row_count), SUM(used_page_count)
   FROM tempdb.sys.dm_db_partition_stats
   WHERE index_id IN (0,1)
   GROUP BY [object_id]
) AS x(id, rc, upc)
ON x.id = o.[object_id]
WHERE gt.DatabaseID = 2 
  AND gt.EventClass = 46 -- (Object:Created Event from sys.trace_events)  
  AND o.create_date >= DATEADD(ms, -100, gt.StartTime)   
  AND o.create_date <= DATEADD(ms, 100, gt.StartTime)
Run Code Online (Sandbox Code Playgroud)

这里的问题是试图通过查询文本关联表名;这只是不切实际,因为在大多数情况下,用户并不仍在对该表执行查询(更不用说仍在运行创建/填充它的表)。

但是,这是针对其他读者(或升级时的您),如果 #temp 表是堆,则2012+ 中的默认跟踪不再跟踪临时表对象创建。不确定这是巧合还是与以下事实直接相关:从 2012 年开始,所有临时表现object_id都有一个否定的. 您当然可以使用 Extended Events 来帮助您收集和跟踪此信息,但这可能需要大量手动工作(并且我仅确认不再跟踪此信息 - 您可能无法选择它在扩展事件中或者)。默认跟踪 选择使用 PK 或其他约束创建的 #temp 表,或者在创建事件之后添加的约束或索引,但是您必须放松上述基于时间的限制(索引可以在 100 毫秒之后创建)创建)。

本网站上的其他一些可能有用的答案:

我还写了一篇关于此的博客,使用自定义扩展事件会话来跟踪 SQL Server 2012 及更高版本中的此信息:

保罗怀特写了关于直接阅读页面的博客(不完全适合胆小的人,也不容易以任何方式自动化):


Tho*_*ger 7

这是一个查询,应该可以让您开始查找您正在寻找的信息:

select top 10
    tsu.session_id,
    tsu.request_id,
    r.command,
    s.login_name,
    s.host_name,
    s.program_name,
    total_objects_alloc_page_count = 
        tsu.user_objects_alloc_page_count + tsu.internal_objects_alloc_page_count,
    tsu.user_objects_alloc_page_count,
    tsu.user_objects_dealloc_page_count,
    tsu.internal_objects_alloc_page_count,
    tsu.internal_objects_dealloc_page_count,
    st.text
from sys.dm_db_task_space_usage tsu
inner join sys.dm_exec_requests r
on tsu.session_id = r.session_id
and tsu.request_id = r.request_id
inner join sys.dm_exec_sessions s
on r.session_id = s.session_id
outer apply sys.dm_exec_sql_text(r.sql_handle) st
where tsu.user_objects_alloc_page_count > 0
or tsu.internal_objects_alloc_page_count > 0
order by total_objects_alloc_page_count desc;
Run Code Online (Sandbox Code Playgroud)

此查询提取前 10 个任务的有用信息,例如分配/解除分配的页面、任务的 SQL 文本(如果可用)等。

这些 DMV 充满了重要信息,因此如果您需要更多数据,那么您可以混合搭配您正在提取的数据。但这应该是对当前 tempdb 消耗任务进行故障排除的起点。