Sql-Server

查找哪個會話持有哪個臨時表

  • August 27, 2021

我們有一個 SQL Server 2005 數據庫,臨時數據庫已滿。通過進入 SQL Server Management Studio,我可以看到 tempdb 中的所有臨時表。是否可以判斷哪個會話持有哪個臨時表?理想情況下,查詢會列出每個會話使用的臨時表。

謝謝,

早在 2007 年,我就要求在 Connect 上建構一些東西。這在 2008 年版本中被拒絕,隨後被忽略,直到幾年前 Connect 死了。我試圖在 SQL Server 的新回饋站點上找到它](它也已被殺死,但該搜尋絕對是垃圾箱之火。我請求的標題是“dmv 將臨時表映射到 session_id” - 因為搜尋可以只做 OR,“map temp table”返回 118 頁的結果。Google似乎暗示該項目在他們殺死 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)

*無恥地從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)

這裡的問題是試圖通過查詢文本關聯表名;這是不切實際的,因為大多數時候,使用者還沒有對該表執行查詢(沒關係仍然執行創建/填充它的那個)

但是,這適用於其他讀者(或升級時的您),如果 #temp 表是堆,則**2012+ 中的預設跟踪不再跟踪臨時表對象創建。**不確定這是巧合還是與從 2012 年開始所有臨時表現在都為負數object_id的事實直接相關。您當然可以轉到擴展事件來幫助您收集和跟踪這些資訊,但這可能需要大量的手動工作(而且我只是驗證了這不再在跟踪中被跟踪 - 您可能無法選擇它在擴展事件中也可以)。預設跟踪選擇使用 PK 或其他約束創建的 #temp 表,或者在創建事件之後添加約束或索引,但是您必須放寬上述基於時間的限制(可以在 100 毫秒之後創建索引創建)。

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

我還寫了一篇關於此的部落格,使用自定義擴展事件會話來跟踪 SQL Server 2012 及更高版本中的此資訊:

Paul White 寫過關於直接閱讀頁面的部落格(不完全適合膽小的人,也不容易以任何方式自動化):

這是一個查詢,可以幫助您開始查找您正在尋找的資訊:

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;

此查詢提取前 10 個任務的有用資訊,例如分配/取消分配的頁面、任務的 SQL 文本(如果可用)等。

這些 DMV 充滿了重要的資訊,因此如果您需要更多數據,那麼您可以混合和匹配您正在提取的內容。但這應該是對目前 tempdb 消耗任務進行故障排除的起點。

引用自:https://dba.stackexchange.com/questions/61703